@@ -1495,7 +1495,7 @@ describe("RepoSelector — org accordion", () => {
14951495// Initial sort order is covered by the existing "shows personal org first" test (line 238).
14961496// S1 and S2 below cover post-sort stability (frozen order unchanged after repo retry and
14971497// checkbox toggle respectively).
1498- // S5 (frozen order in accordion mode with pre-loaded entries) is deferred pending accordion merge .
1498+ // S5 below covers retry stability in accordion mode (aria-expanded preservation after retry) .
14991499
15001500describe ( "RepoSelector — frozen org order" , ( ) => {
15011501 function makeOrgRepos ( org : string ) : RepoEntry [ ] {
@@ -1709,6 +1709,76 @@ describe("RepoSelector — frozen org order", () => {
17091709 expect ( getAccordionOrder ( newOrgs ) ) . toEqual ( [ "alice" , "acme-corp" , "beta-org" , "charlie-co" , "delta-inc" , "echo-labs" , "foxtrot-io" ] ) ;
17101710 } ) ;
17111711
1712+ // S5: Org order stable with 7 orgs after retry in accordion mode
1713+ it ( "org order stable with 7 orgs after retry in accordion mode (S5)" , async ( ) => {
1714+ const sevenOrgs = [ "alice" , "acme-corp" , "beta-org" , "charlie-co" , "delta-inc" , "echo-labs" , "foxtrot-io" ] ;
1715+ const sevenEntries = sevenOrgs . map ( ( login ) => ( {
1716+ login,
1717+ avatarUrl : "" ,
1718+ type : login === "alice" ? ( "user" as const ) : ( "org" as const ) ,
1719+ } ) ) ;
1720+
1721+ vi . mocked ( api . fetchRepos ) . mockImplementation ( ( _client , org ) => {
1722+ if ( org === "echo-labs" ) return Promise . reject ( new Error ( "echo load failed" ) ) ;
1723+ return Promise . resolve ( makeOrgRepos ( org as string ) ) ;
1724+ } ) ;
1725+
1726+ render ( ( ) => (
1727+ < RepoSelector
1728+ selectedOrgs = { sevenOrgs }
1729+ orgEntries = { sevenEntries }
1730+ selected = { [ ] }
1731+ onChange = { vi . fn ( ) }
1732+ />
1733+ ) ) ;
1734+
1735+ // Wait for accordion mode to render
1736+ await waitFor ( ( ) => {
1737+ screen . getByRole ( "button" , { name : / a l i c e / } ) ;
1738+ } ) ;
1739+
1740+ // Expand echo-labs to reveal its error state and Retry button
1741+ const echoBtn = screen . getByRole ( "button" , { name : / e c h o - l a b s / } ) ;
1742+ fireEvent . click ( echoBtn ) ;
1743+ expect ( echoBtn . getAttribute ( "aria-expanded" ) ) . toBe ( "true" ) ;
1744+
1745+ await waitFor ( ( ) => {
1746+ screen . getByText ( "Retry" ) ;
1747+ } ) ;
1748+
1749+ // Verify initial sorted order via accordion trigger buttons
1750+ const getAccordionOrder = ( orgNames : string [ ] ) =>
1751+ orgNames
1752+ . map ( ( name ) => ( { name, btn : screen . getByRole ( "button" , { name : new RegExp ( name ) } ) } ) )
1753+ . sort ( ( a , b ) => {
1754+ const pos = a . btn . compareDocumentPosition ( b . btn ) ;
1755+ return pos & Node . DOCUMENT_POSITION_FOLLOWING ? - 1 : 1 ;
1756+ } )
1757+ . map ( ( { name } ) => name ) ;
1758+
1759+ const initialOrder = getAccordionOrder ( sevenOrgs ) ;
1760+ expect ( initialOrder ) . toEqual ( [ "alice" , "acme-corp" , "beta-org" , "charlie-co" , "delta-inc" , "echo-labs" , "foxtrot-io" ] ) ;
1761+
1762+ // Set up retry to succeed
1763+ vi . mocked ( api . fetchRepos ) . mockImplementation ( ( _client , org ) =>
1764+ Promise . resolve ( makeOrgRepos ( org as string ) )
1765+ ) ;
1766+
1767+ fireEvent . click ( screen . getByText ( "Retry" ) ) ;
1768+
1769+ await waitFor ( ( ) => {
1770+ screen . getByText ( "echo-labs-repo" ) ;
1771+ } ) ;
1772+
1773+ // Order must be unchanged after retry
1774+ const orderAfterRetry = getAccordionOrder ( sevenOrgs ) ;
1775+ expect ( orderAfterRetry ) . toEqual ( [ "alice" , "acme-corp" , "beta-org" , "charlie-co" , "delta-inc" , "echo-labs" , "foxtrot-io" ] ) ;
1776+
1777+ // The expanded panel (echo-labs) must remain expanded
1778+ const echoBtnAfter = screen . getByRole ( "button" , { name : / e c h o - l a b s / } ) ;
1779+ expect ( echoBtnAfter . getAttribute ( "aria-expanded" ) ) . toBe ( "true" ) ;
1780+ } ) ;
1781+
17121782 // S7: Frozen order invalidated on simultaneous add and remove
17131783 // Uses aaa-org (sorts BEFORE acme-corp alphabetically) to expose the stale-freeze bug:
17141784 // if the freeze is not invalidated, aaa-org would be appended at the end instead
0 commit comments