-
Notifications
You must be signed in to change notification settings - Fork 4
86b82fa34 - feat: add url fragment linking to tabs on edit sponsor page #751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughThe edit sponsor page was changed to drive tab selection via URL hash fragments: added a tab-to-fragment map and helpers, initialize selected tab from window.location.hash, sync state on external hash changes, and update window.location.hash when tabs change. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser
participant PageComponent
participant TabState
Note over Browser,PageComponent: Initial load
Browser->>PageComponent: load URL (may include `#fragment`)
PageComponent->>Browser: read window.location.hash
PageComponent->>PageComponent: getTabFromUrlFragment()
PageComponent->>TabState: set selectedTab
Note over Browser,PageComponent: User selects a tab
Browser->>PageComponent: click tab
PageComponent->>PageComponent: onTabChange -> getFragmentFromValue()
PageComponent->>Browser: set window.location.hash
PageComponent->>TabState: update selectedTab
Note over Browser,PageComponent: External hash change
Browser->>PageComponent: window.location.hash changes
PageComponent->>PageComponent: useEffect observes change
PageComponent->>TabState: resync selectedTab
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @src/pages/sponsors/edit-sponsor-page.js:
- Around line 116-118: The useEffect using window.location.hash in the
dependency array won't re-run on hash changes; replace it with a hashchange
event listener: in the effect that currently calls
setSelectedTab(getTabFromUrlFragment()), register
window.addEventListener('hashchange', handler) where handler calls
setSelectedTab(getTabFromUrlFragment()), call the handler once on mount to
initialize, and remove the listener in the cleanup; remove window.location.hash
from the dependency array (use []).
🧹 Nitpick comments (1)
src/pages/sponsors/edit-sponsor-page.js (1)
46-64: Helper functions look good, consider consolidating the tab definition.The mapping and helper functions are well-structured. The fallback to index 0 for unrecognized fragments correctly implements the PR requirement.
Consider deriving
tabsToFragmentMapfrom thetabsarray (or vice versa) to avoid maintaining two separate lists that must stay in sync. For now, this is acceptable.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/pages/sponsors/edit-sponsor-page.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (2)
src/pages/sponsors/edit-sponsor-page.js (2)
120-123: LGTM!Setting
window.location.hashcorrectly updates the URL and adds a browser history entry, enabling back/forward navigation between tabs.
155-155: Formatting change acknowledged.Minor whitespace adjustment in the sx prop—no functional impact.
smarcet
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@niko-exo please review
| const result = tabsToFragmentMap.indexOf( | ||
| window.location.hash.replace("#", "") | ||
| ); | ||
| return result > -1 ? result : 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
on the initial load
general tab should be selected hence #general should be show by default
if (result > -1) return result;
if (window.location.hash) window.location.hash = "general";
return 0
```;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup! If the general fragment is provided, then it will use it. If not it will retrieve 0, which means use the general fragment. Note that the general fragment is included on the 0 position of the array above the function. I think this function is performing what you mean.
22f0d4b to
9c4adf3
Compare
|
#756 Unblocks this pull request. |
* Add test id to make testing more feasible.
9c4adf3 to
c3e31c6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@src/pages/sponsors/__tests__/edit-sponsor-page.test.js`:
- Around line 144-151: The test's assertion expects window.location.hash without
the leading '#' but JSDOM stores hashes with the '#' prefix; update the
assertion in src/pages/sponsors/__tests__/edit-sponsor-page.test.js to expect
"#forms" instead of "forms" (the component sets the fragment via
getFragmentFromValue() in edit-sponsor-page.js which returns values without '#',
but window.location.hash will include it). Ensure any other assertions in this
test that check window.location.hash are adjusted the same way.
- Line 17: Remove the global.window override that stubs the entire JSDOM window
(the line `global.window = { location: { pathname: "/sponsor-forms/items" } };`)
so tests use the real JSDOM window and its Location API; rely on existing test
setup that uses Object.defineProperty to modify window.location or
window.location.hash when needed, and ensure no other tests expect the stubbed
object.
- Around line 153-217: The test currently only checks existence of tab panels
which is a false positive because CustomTabPanel renders all panels
hidden/visible; update the test to wait for the component to react to the hash
change (use waitFor or findByTestId) and assert visibility instead of mere
existence: after setting location.hash="#general" wait for simple-tabpanel-0 to
be visible (expect(...).toBeVisible()) and that simple-tabpanel-1 is hidden
(expect(...).not.toBeVisible() or expect(...).toHaveAttribute('hidden')); then
after setting hash="#users" wait for simple-tabpanel-1 to be visible and assert
simple-tabpanel-0 is hidden. Use screen.findByTestId or waitFor +
screen.getByTestId and the jest-dom matchers to check visibility; target the
test wrapping EditSponsorPage and the simple-tabpanel-* test ids.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/pages/sponsors/__tests__/edit-sponsor-page.test.jssrc/pages/sponsors/edit-sponsor-page.jssrc/reducers/sponsors/sponsor-reducer.jssrc/reducers/summits/current-summit-reducer.js
🚧 Files skipped from review as they are similar to previous changes (1)
- src/pages/sponsors/edit-sponsor-page.js
🧰 Additional context used
🧬 Code graph analysis (2)
src/reducers/sponsors/sponsor-reducer.js (15)
src/reducers/summits/current-summit-reducer.js (2)
DEFAULT_STATE(217-223)DEFAULT_STATE(217-223)src/reducers/payment_profiles/payment-profile-reducer.js (1)
DEFAULT_STATE(39-42)src/reducers/sponsors/sponsor-customized-form-reducer.js (1)
DEFAULT_STATE(41-43)src/reducers/sponsors/sponsor-page-forms-list-reducer.js (1)
DEFAULT_STATE(29-51)src/reducers/sponsors/sponsor-list-reducer.js (1)
DEFAULT_STATE(25-34)src/reducers/badges/badge-feature-list-reducer.js (1)
DEFAULT_STATE(23-28)src/reducers/sponsors/sponsor-social-network-reducer.js (1)
DEFAULT_STATE(35-38)src/reducers/sponsors/sponsor-material-reducer.js (1)
DEFAULT_STATE(36-39)src/reducers/badges/badge-type-reducer.js (1)
DEFAULT_STATE(42-45)src/reducers/sponsors/sponsor-advertisement-reducer.js (1)
DEFAULT_STATE(39-42)src/reducers/badges/access-level-list-reducer.js (1)
DEFAULT_STATE(23-28)src/reducers/badges/badge-type-list-reducer.js (1)
DEFAULT_STATE(23-28)src/reducers/badges/access-level-reducer.js (1)
DEFAULT_STATE(34-37)src/reducers/badges/badge-feature-reducer.js (1)
DEFAULT_STATE(36-39)src/reducers/refund_policies/refund-policy-list-reducer.js (1)
DEFAULT_STATE(25-30)
src/reducers/summits/current-summit-reducer.js (16)
src/reducers/events/summit-event-reducer.js (1)
DEFAULT_STATE(108-115)src/reducers/tickets/ticket-list-reducer.js (1)
DEFAULT_STATE(28-45)src/reducers/tickets/ticket-reducer.js (1)
DEFAULT_STATE(63-67)src/reducers/attendees/attendee-reducer.js (1)
DEFAULT_STATE(56-59)src/reducers/promocodes/promocode-reducer.js (1)
DEFAULT_STATE(78-83)src/reducers/tickets/ticket-type-reducer.js (1)
DEFAULT_STATE(42-45)src/reducers/events/event-type-reducer.js (1)
DEFAULT_STATE(62-65)src/reducers/locations/location-list-reducer.js (1)
DEFAULT_STATE(24-28)src/reducers/locations/room-reducer.js (1)
DEFAULT_STATE(47-50)src/reducers/events/event-category-list-reducer.js (1)
DEFAULT_STATE(25-27)src/reducers/events/event-category-reducer.js (1)
DEFAULT_STATE(51-55)src/reducers/speakers/speaker-reducer.js (1)
DEFAULT_STATE(52-55)src/reducers/events/event-material-reducer.js (1)
DEFAULT_STATE(42-45)src/reducers/badges/badge-type-reducer.js (1)
DEFAULT_STATE(42-45)src/reducers/locations/floor-reducer.js (1)
DEFAULT_STATE(37-40)src/reducers/locations/location-reducer.js (1)
DEFAULT_STATE(67-71)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: build
- GitHub Check: build
- GitHub Check: build
- GitHub Check: build
- GitHub Check: build
- GitHub Check: build
🔇 Additional comments (2)
src/reducers/sponsors/sponsor-reducer.js (1)
135-139: LGTM — exportingDEFAULT_STATEis consistent and safe.
This aligns with the repo pattern for reducer default state access.src/reducers/summits/current-summit-reducer.js (1)
217-223: LGTM —DEFAULT_STATEexport is a clean consistency update.
No behavioral impact, just improved reuse.
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| DEFAULT_STATE as currentSummitDefaultState | ||
| } from "../../../reducers/summits/current-summit-reducer"; | ||
|
|
||
| global.window = { location: { pathname: "/sponsor-forms/items" } }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# Step 1: Verify EditSponsorPage uses hashchange/addEventListener so the real window APIs are required
rg -n "hashchange|addEventListener\(|window\.location\.hash" src/pages/sponsors/edit-sponsor-page.jsRepository: fntechgit/summit-admin
Length of output: 207
🏁 Script executed:
# Step 2: Examine the test file around line 17 to understand context
head -50 src/pages/sponsors/__tests__/edit-sponsor-page.test.js | cat -nRepository: fntechgit/summit-admin
Length of output: 2017
🏁 Script executed:
# Step 3: Check if there are hash-change tests and understand what the test is doing
rg -n "hashchange|addEventListener|location\.hash" src/pages/sponsors/__tests__/edit-sponsor-page.test.js -A 3 -B 3Repository: fntechgit/summit-admin
Length of output: 1833
🏁 Script executed:
# Step 4: Examine the actual component implementation to understand hash handling
cat -n src/pages/sponsors/edit-sponsor-page.js | head -150Repository: fntechgit/summit-admin
Length of output: 5445
🏁 Script executed:
# Step 5: Look for useEffect and hash change logic in the component
rg -n "useEffect|hashchange|addEventListener" src/pages/sponsors/edit-sponsor-page.js -B 2 -A 5Repository: fntechgit/summit-admin
Length of output: 873
🏁 Script executed:
# Step 6: Check if there's any listener setup or initialization in the component
sed -n '50,200p' src/pages/sponsors/edit-sponsor-page.js | cat -nRepository: fntechgit/summit-admin
Length of output: 5213
🏁 Script executed:
# Check the specific test that asserts hash value at line 150
sed -n '140,160p' src/pages/sponsors/__tests__/edit-sponsor-page.test.js | cat -nRepository: fntechgit/summit-admin
Length of output: 732
🏁 Script executed:
# Check if there are any other tests that involve hash manipulation or tab changes
rg -n "should change the tab|fragment change" src/pages/sponsors/__tests__/edit-sponsor-page.test.js -A 20Repository: fntechgit/summit-admin
Length of output: 652
🏁 Script executed:
# Check what the full test file looks like to understand the testing strategy
wc -l src/pages/sponsors/__tests__/edit-sponsor-page.test.jsRepository: fntechgit/summit-admin
Length of output: 124
🏁 Script executed:
# Check where originalWindowLocation is defined and what it contains
rg -n "originalWindowLocation" src/pages/sponsors/__tests__/edit-sponsor-page.test.js -B 5 -A 2Repository: fntechgit/summit-admin
Length of output: 1197
🏁 Script executed:
# View the complete test to understand setup/teardown
head -30 src/pages/sponsors/__tests__/edit-sponsor-page.test.js | cat -nRepository: fntechgit/summit-admin
Length of output: 1348
🏁 Script executed:
# Check if there's a beforeEach or beforeAll that might be resetting window
rg -n "beforeEach|beforeAll|afterEach|afterAll" src/pages/sponsors/__tests__/edit-sponsor-page.test.js -A 5Repository: fntechgit/summit-admin
Length of output: 245
Remove the global.window override — it prevents JSDOM's Location API from functioning properly.
Line 17 replaces the entire JSDOM window with a minimal stub. This becomes the "reference" used by tests, preventing proper Location semantics when later tests try to mock window.location.hash. Remove the override and keep the real JSDOM window; tests already reset window.location as needed via Object.defineProperty in their setup.
Fix
- global.window = { location: { pathname: "/sponsor-forms/items" } };📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| global.window = { location: { pathname: "/sponsor-forms/items" } }; |
🤖 Prompt for AI Agents
In `@src/pages/sponsors/__tests__/edit-sponsor-page.test.js` at line 17, Remove
the global.window override that stubs the entire JSDOM window (the line
`global.window = { location: { pathname: "/sponsor-forms/items" } };`) so tests
use the real JSDOM window and its Location API; rely on existing test setup that
uses Object.defineProperty to modify window.location or window.location.hash
when needed, and ensure no other tests expect the stubbed object.
| const usersTabReference = screen.getByText("edit_sponsor.tab.forms"); | ||
|
|
||
| await act(async () => { | ||
| await userEvent.click(usersTabReference); | ||
| }); | ||
|
|
||
| expect(window.location.hash).toBe("forms"); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, find and read the test file
cat -n src/pages/sponsors/__tests__/edit-sponsor-page.test.js | head -200Repository: fntechgit/summit-admin
Length of output: 6883
🏁 Script executed:
# Find and read the EditSponsorPage component
cat -n src/pages/sponsors/edit-sponsor-page.js | head -300Repository: fntechgit/summit-admin
Length of output: 11190
Fix hash format to match JSDOM behavior.
window.location.hash always includes the leading # when accessed in real JSDOM. The component assigns "forms" (line 129 of edit-sponsor-page.js calls getFragmentFromValue() which returns fragment values without #), but the test assertion should expect the actual stored value with the # prefix.
🔧 Suggested fix
- expect(window.location.hash).toBe("forms");
+ expect(window.location.hash).toBe("#forms");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const usersTabReference = screen.getByText("edit_sponsor.tab.forms"); | |
| await act(async () => { | |
| await userEvent.click(usersTabReference); | |
| }); | |
| expect(window.location.hash).toBe("forms"); | |
| }); | |
| const usersTabReference = screen.getByText("edit_sponsor.tab.forms"); | |
| await act(async () => { | |
| await userEvent.click(usersTabReference); | |
| }); | |
| expect(window.location.hash).toBe("#forms"); | |
| }); |
🤖 Prompt for AI Agents
In `@src/pages/sponsors/__tests__/edit-sponsor-page.test.js` around lines 144 -
151, The test's assertion expects window.location.hash without the leading '#'
but JSDOM stores hashes with the '#' prefix; update the assertion in
src/pages/sponsors/__tests__/edit-sponsor-page.test.js to expect "#forms"
instead of "forms" (the component sets the fragment via getFragmentFromValue()
in edit-sponsor-page.js which returns values without '#', but
window.location.hash will include it). Ensure any other assertions in this test
that check window.location.hash are adjusted the same way.
| it("should change the tab rendered on fragment change", async () => { | ||
| delete window.location; | ||
|
|
||
| Object.defineProperty(window, "location", { | ||
| configurable: true, | ||
| writable: true, | ||
| value: { | ||
| ...originalWindowLocation, | ||
| hash: "#general" | ||
| } | ||
| }); | ||
|
|
||
| renderWithRedux( | ||
| <EditSponsorPage | ||
| history={{}} | ||
| location={{ | ||
| pathname: "/sponsor-forms/items" | ||
| }} | ||
| match={{}} | ||
| />, | ||
| { | ||
| initialState: { | ||
| currentSummitState: { | ||
| currentSummit: defaultSummitEntity, | ||
| ...currentSummitDefaultState | ||
| }, | ||
| loggedUserState: { | ||
| member: { | ||
| groups: {} | ||
| } | ||
| }, | ||
| currentSummitSponsorshipListState: { | ||
| sponsorships: [], | ||
| currentPage: 1, | ||
| lastPage: 1, | ||
| perPage: 100, | ||
| order: "order", | ||
| orderDir: 1, | ||
| totalSponsorships: 0 | ||
| }, | ||
| currentSponsorState: { | ||
| sponsorships: [], | ||
| ...currentSponsorDefaultState | ||
| } | ||
| } | ||
| } | ||
| ); | ||
|
|
||
| const generalTabPanel = screen.getByTestId("simple-tabpanel-0"); | ||
| expect(generalTabPanel).toBeDefined(); | ||
|
|
||
| delete window.location; | ||
|
|
||
| Object.defineProperty(window, "location", { | ||
| configurable: true, | ||
| writable: true, | ||
| value: { | ||
| ...originalWindowLocation, | ||
| hash: "#users" | ||
| } | ||
| }); | ||
|
|
||
| const usersTabPanel = screen.getByTestId("simple-tabpanel-1"); | ||
| expect(usersTabPanel).toBeDefined(); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
# First, confirm the test file exists and check the code around lines 153-217
fd "edit-sponsor-page.test.js" --type fRepository: fntechgit/summit-admin
Length of output: 120
🏁 Script executed:
# Find and explore the test file
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | sed -n '140,220p'Repository: fntechgit/summit-admin
Length of output: 2648
🏁 Script executed:
# Check the EditSponsorPage component to see how it handles hash changes
fd "edit-sponsor-page" --type f | grep -v test | grep -v ".test"Repository: fntechgit/summit-admin
Length of output: 105
🏁 Script executed:
# Examine the EditSponsorPage component to understand how it handles hash changes
cat -n "src/pages/sponsors/edit-sponsor-page.js" | head -150Repository: fntechgit/summit-admin
Length of output: 5445
🏁 Script executed:
# Search for hashchange or hash-related event listeners in the component
rg "hashchange|window.location.hash|hash" "src/pages/sponsors/edit-sponsor-page.js" -A 3 -B 2Repository: fntechgit/summit-admin
Length of output: 502
🏁 Script executed:
# Check if the component uses useEffect to listen to hash changes
ast-grep --pattern 'useEffect($$$)' "src/pages/sponsors/edit-sponsor-page.js"Repository: fntechgit/summit-admin
Length of output: 1168
🏁 Script executed:
# Check the test setup and imports to see what testing utilities are available
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | head -50Repository: fntechgit/summit-admin
Length of output: 2017
🏁 Script executed:
# Search for how hashchange is handled elsewhere in tests
rg "hashchange|HashChangeEvent" --type js -iRepository: fntechgit/summit-admin
Length of output: 164
🏁 Script executed:
# Check if there's a custom hook or utility for managing hash-based routing
rg "getTabFromUrlFragment|getFragmentFromValue" --type js -A 2 -B 2Repository: fntechgit/summit-admin
Length of output: 6929
🏁 Script executed:
# Check if there are other tests that use hashchange or similar patterns
rg "hashchange|HashChangeEvent|window.dispatchEvent" --type js -B 2 -A 2Repository: fntechgit/summit-admin
Length of output: 488
🏁 Script executed:
# Look at the complete test to see if there's proper act() wrapping or waitFor
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | sed -n '100,220p'Repository: fntechgit/summit-admin
Length of output: 3955
🏁 Script executed:
# Check package.json to see what testing libraries are available
rg "testing-library|jest" package.jsonRepository: fntechgit/summit-admin
Length of output: 525
🏁 Script executed:
# Check if the component has any hashchange event listeners
cat -n "src/pages/sponsors/edit-sponsor-page.js" | grep -A 20 "useEffect"Repository: fntechgit/summit-admin
Length of output: 1893
🏁 Script executed:
# Verify the CustomTabPanel implementation to understand the hidden/visibility logic
cat -n "src/pages/sponsors/edit-sponsor-page.js" | sed -n '69,84p'Repository: fntechgit/summit-admin
Length of output: 570
🏁 Script executed:
# Check if other components in the codebase listen to hashchange and how they do it
rg "addEventListener.*hash|window.onhashchange" --type js -B 3 -A 5Repository: fntechgit/summit-admin
Length of output: 788
🏁 Script executed:
# Check how other tests in this file handle async state changes and waits
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | sed -n '70,105p'Repository: fntechgit/summit-admin
Length of output: 1237
🏁 Script executed:
# Search for patterns of waiting for effects in similar tests
rg "waitFor|act.*hash|fireEvent" "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" -A 3 -B 1Repository: fntechgit/summit-admin
Length of output: 48
🏁 Script executed:
# Check if there are other tests that verify visibility of rendered elements
rg "toBeVisible|hidden|role.*tabpanel" --type js -B 2 -A 2 | head -40Repository: fntechgit/summit-admin
Length of output: 3005
🏁 Script executed:
# Let's look at the complete test and see if there's any waiting mechanism
cat -n "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" | sed -n '150,225p'Repository: fntechgit/summit-admin
Length of output: 2503
🏁 Script executed:
# Check if renderWithRedux or test setup does anything special with effects
rg "renderWithRedux|beforeEach|afterEach" "src/pages/sponsors/__tests__/edit-sponsor-page.test.js" -A 10 -B 1Repository: fntechgit/summit-admin
Length of output: 1185
🏁 Script executed:
# Verify how React's useEffect dependency works - check if the component actually responds to hash changes at runtime
cat -n "src/pages/sponsors/edit-sponsor-page.js" | sed -n '119,135p'Repository: fntechgit/summit-admin
Length of output: 640
🏁 Script executed:
# Check if there are any imports of fireEvent or other event simulation tools in the test
head -30 "src/pages/sponsors/__tests__/edit-sponsor-page.test.js"Repository: fntechgit/summit-admin
Length of output: 1138
🏁 Script executed:
# Verify if jest-dom provides toBeVisible matcher
rg "jest-dom|toBeVisible|toHaveAttribute" "src/pages/sponsors/__tests__/edit-sponsor-page.test.js"Repository: fntechgit/summit-admin
Length of output: 48
🏁 Script executed:
# Check if the component implementation actually listens to hashchange events
rg "addEventListener.*hashchange|on.*hashchange|onhashchange" "src/pages/sponsors/edit-sponsor-page.js"Repository: fntechgit/summit-admin
Length of output: 48
🏁 Script executed:
# Check if jest-dom is set up in a setup file
fd "setup" --type f | grep -i jestRepository: fntechgit/summit-admin
Length of output: 48
🏁 Script executed:
# Look for jest configuration to see if jest-dom is imported
rg "setupFilesAfterEnv|testEnvironment" package.json -A 3Repository: fntechgit/summit-admin
Length of output: 170
🏁 Script executed:
# Test a hypothesis: check if the component would even work correctly with the dependency on window.location.hash
# Search for similar useEffect patterns with window.location
rg "useEffect.*window.location|dependency.*window" --type js -B 2 -A 3Repository: fntechgit/summit-admin
Length of output: 48
🏁 Script executed:
# Let's check the test setup file to understand the environment better
cat "testSetupFile.js" | head -50Repository: fntechgit/summit-admin
Length of output: 182
🏁 Script executed:
# Verify if the CustomTabPanel's hidden attribute actually hides elements testable with toBeVisible
rg "hidden.*attribute|aria-hidden|display.*none" "src/pages/sponsors/edit-sponsor-page.js" -B 2 -A 2Repository: fntechgit/summit-admin
Length of output: 48
🏁 Script executed:
# Let's trace through what happens - check if there's any event listener setup elsewhere
rg "addEventListener" "src/pages/sponsors/edit-sponsor-page.js"Repository: fntechgit/summit-admin
Length of output: 48
🏁 Script executed:
# Check the complete rendering of the component to see all tabs
cat -n "src/pages/sponsors/edit-sponsor-page.js" | sed -n '170,250p'Repository: fntechgit/summit-admin
Length of output: 3688
🏁 Script executed:
# Verify the exact behavior: does the component update when window.location.hash changes at runtime?
# Let's check if maybe there's a different mechanism (like router props) that drives updates
cat -n "src/pages/sponsors/edit-sponsor-page.js" | sed -n '90,130p'Repository: fntechgit/summit-admin
Length of output: 1384
Assert tab visibility, not just existence.
The test changes window.location.hash but doesn't wait for the component to respond, and only checks toBeDefined() on tab panels. Since CustomTabPanel renders all panels in the DOM (with hidden={value !== index}), checking existence is a false positive—panels exist but may be hidden. Assert that the active panel is visible and the previous one is not.
🔧 Suggested fix
Object.defineProperty(window, "location", {
configurable: true,
writable: true,
value: {
...originalWindowLocation,
hash: "#users"
}
});
+ window.dispatchEvent(new HashChangeEvent("hashchange"));
const usersTabPanel = screen.getByTestId("simple-tabpanel-1");
- expect(usersTabPanel).toBeDefined();
+ expect(usersTabPanel).toBeVisible();
+ expect(generalTabPanel).not.toBeVisible();🤖 Prompt for AI Agents
In `@src/pages/sponsors/__tests__/edit-sponsor-page.test.js` around lines 153 -
217, The test currently only checks existence of tab panels which is a false
positive because CustomTabPanel renders all panels hidden/visible; update the
test to wait for the component to react to the hash change (use waitFor or
findByTestId) and assert visibility instead of mere existence: after setting
location.hash="#general" wait for simple-tabpanel-0 to be visible
(expect(...).toBeVisible()) and that simple-tabpanel-1 is hidden
(expect(...).not.toBeVisible() or expect(...).toHaveAttribute('hidden')); then
after setting hash="#users" wait for simple-tabpanel-1 to be visible and assert
simple-tabpanel-0 is hidden. Use screen.findByTestId or waitFor +
screen.getByTestId and the jest-dom matchers to check visibility; target the
test wrapping EditSponsorPage and the simple-tabpanel-* test ids.
|
Ready for review @smarcet |
ref: https://app.clickup.com/t/86b82fa34
86b82fa34 - feat: add url fragment linking to tabs on edit sponsor page
Changelog
Links
86b82fa34 - Add TAB deep-linking using URL fragment
Evidence
2026-01-12_09-56-27.mp4
Summary by CodeRabbit
New Features
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.