@@ -686,12 +686,15 @@ test.describe("MIDI Studio V2", () => {
686686 await expect ( octaveTimelineCanvas ( page ) ) . toBeVisible ( ) ;
687687 await expect ( page . locator ( ".midi-studio-v2__octave-note-cell" ) ) . toHaveCount ( 0 ) ;
688688 await expect ( page . locator ( ".midi-studio-v2__grid-cell--timing-header" ) ) . toHaveCount ( 0 ) ;
689+ await expect ( page . locator ( ".midi-studio-v2__instrument-list-panel" ) ) . toBeHidden ( ) ;
690+ await selectMidiStudioTab ( page , "instruments" ) ;
689691 await expect ( instrumentTypeSelect ( page , "lead" ) ) . toHaveJSProperty ( "tagName" , "SELECT" ) ;
690692 await expect ( instrumentSelect ( page , "lead" ) ) . toHaveJSProperty ( "tagName" , "SELECT" ) ;
691693 await expect ( page . locator ( "#playButton" ) ) . toHaveJSProperty ( "tagName" , "BUTTON" ) ;
692694 await expect ( page . locator ( "#toolImportManifestInput" ) ) . toHaveJSProperty ( "tagName" , "INPUT" ) ;
693695
694696 await selectInstrumentRow ( page , "lead" ) ;
697+ await selectMidiStudioTab ( page , "studio" ) ;
695698 await waitForCanvasRender ( page ) ;
696699 const initialCanvasState = await canvasTimelineState ( page ) ;
697700 expect ( initialCanvasState . rows . some ( ( row ) => row . value === "C6" ) ) . toBe ( true ) ;
@@ -1883,7 +1886,7 @@ test.describe("MIDI Studio V2", () => {
18831886 }
18841887 } ) ;
18851888
1886- test ( "cleans up Song Setup tab and keeps song changes canonical " , async ( { page } ) => {
1889+ test ( "restores Song Setup editable buckets without duplicating diagnostics " , async ( { page } ) => {
18871890 const server = await openMidiStudioForImport ( page ) ;
18881891 try {
18891892 await page . locator ( "#toolImportManifestInput" ) . setInputFiles ( uatManifestPath ) ;
@@ -1897,73 +1900,99 @@ test.describe("MIDI Studio V2", () => {
18971900 ] ) ;
18981901 expect ( tabs . map ( ( tab ) => tab . text ) ) . not . toContain ( "Studio" ) ;
18991902 await expect ( page . locator ( '[data-midi-studio-tab="song-setup"]' ) ) . toHaveAttribute ( "aria-selected" , "true" ) ;
1903+ await expect ( page . locator ( '.accordion-v2__header[aria-controls="songListContent"]' ) ) . toContainText ( "Songs" ) ;
1904+ await expect ( page . locator ( '.accordion-v2__header[aria-controls="songDetailsContent"]' ) ) . toContainText ( "Song Details" ) ;
1905+ await expect ( page . locator ( '.accordion-v2__header[aria-controls="songSheetContent"]' ) ) . toContainText ( "Song Sheet" ) ;
1906+ await expect ( page . locator ( '.accordion-v2__header[aria-controls="songSectionsLoopContent"]' ) ) . toContainText ( "Sections / Loop" ) ;
1907+ await expect ( page . locator ( '.accordion-v2__header[aria-controls="statusLogContent"]' ) ) . toContainText ( "Status" ) ;
19001908 await expect ( page . locator ( "#songDetailsContent" ) ) . toBeVisible ( ) ;
1901- await expect ( page . locator ( "#songDetailsContent # songSheetContent" ) ) . toHaveCount ( 1 ) ;
1902- await expect ( page . locator ( "#songDetailsContent #songSheetSummary " ) ) . toHaveCount ( 0 ) ;
1909+ await expect ( page . locator ( "#songSheetContent" ) ) . toBeVisible ( ) ;
1910+ await expect ( page . locator ( "#songSectionsLoopContent " ) ) . toBeVisible ( ) ;
19031911 await expect ( page . locator ( "#songSheetSummaryContent" ) ) . toHaveCount ( 0 ) ;
1904- await expect ( page . locator ( "#songDetails input[data-song-detail-field]" ) ) . toHaveCount ( 0 ) ;
1905- await expect ( page . locator ( "#songDetails" ) ) . toBeHidden ( ) ;
1906- await expect ( page . locator ( "#directorContent" ) ) . toBeHidden ( ) ;
1907- await expect ( page . locator ( "#renderedTargetsContent" ) ) . toBeHidden ( ) ;
1908- await expect ( page . locator ( "#songSheetKeyInput" ) ) . toBeVisible ( ) ;
1912+ await expect ( page . locator ( "#songSheetContent #songSheetSummary" ) ) . toHaveCount ( 1 ) ;
1913+ expect ( await page . locator ( "#songDetailsContent" ) . evaluate ( ( details ) => {
1914+ const sheet = document . querySelector ( "#songSheetContent" ) ;
1915+ return Boolean ( sheet && details . compareDocumentPosition ( sheet ) & Node . DOCUMENT_POSITION_FOLLOWING ) ;
1916+ } ) ) . toBe ( true ) ;
1917+ await expect ( page . locator ( "#songDetails [data-song-detail-field='name']" ) ) . toHaveValue ( "Camptown Races UAT Reel" ) ;
1918+ await expect ( page . locator ( "#songDetails [data-song-detail-field='id']" ) ) . toHaveValue ( "camptown-races-uat-reel" ) ;
1919+ await expect ( page . locator ( "#songSheetTempoInput" ) ) . toHaveValue ( "144" ) ;
19091920 await expect ( page . locator ( "#songSheetKeyInput" ) ) . toHaveJSProperty ( "tagName" , "SELECT" ) ;
19101921 await expect ( page . locator ( "#songSheetKeyInput" ) ) . toHaveValue ( "G major" ) ;
1911- await expect ( page . locator ( "#songSheetStyleInput" ) ) . toBeVisible ( ) ;
19121922 await expect ( page . locator ( "#songSheetStyleInput" ) ) . toHaveJSProperty ( "tagName" , "SELECT" ) ;
19131923 await expect ( page . locator ( "#songSheetStyleInput" ) ) . toHaveValue ( "public-domain-reel" ) ;
1914- const trailingSpace = await page . locator ( "#songDetailsContent" ) . evaluate ( ( content ) => {
1915- const sheet = content . querySelector ( "#songSheetContent" ) . getBoundingClientRect ( ) ;
1916- const bounds = content . getBoundingClientRect ( ) ;
1917- return Math . round ( bounds . bottom - sheet . bottom ) ;
1918- } ) ;
1919- expect ( trailingSpace ) . toBeLessThanOrEqual ( 16 ) ;
1924+ await expect ( page . locator ( "#songDetails [data-song-detail-field='tags']" ) ) . toHaveValue ( "uat, upbeat, traditional, public-domain" ) ;
1925+ await expect ( page . locator ( "#songDetails [data-song-detail-field='usage']" ) ) . toHaveValue ( "uat, public-domain, preview-synth" ) ;
1926+ await expect ( page . locator ( "#songDetails [data-song-detail-field='notes']" ) ) . toHaveValue ( "Traditional Camptown Races style public-domain test arrangement with lead, bass, chords/pad, and drums." ) ;
1927+ await expect ( page . locator ( "#songSectionsLoopDetails [data-song-detail-field='sections']" ) ) . toHaveValue ( "verse:2, chorus:2" ) ;
1928+ await expect ( page . locator ( "#songSectionsLoopDetails [data-song-detail-field='loopEnabled']" ) ) . toBeChecked ( ) ;
1929+ await expect ( page . locator ( "#directorContent" ) ) . toBeHidden ( ) ;
1930+ await expect ( page . locator ( "#renderedTargetsContent" ) ) . toBeHidden ( ) ;
1931+ await expect ( page . locator ( "#playbackContent" ) ) . toBeHidden ( ) ;
1932+ await expect ( page . locator ( "#audioDiagnosticsContent" ) ) . toBeHidden ( ) ;
1933+ await expect ( page . locator ( "#instrumentGridSummaryContent" ) ) . toBeHidden ( ) ;
1934+ await expect ( page . locator ( "#midiImportContent" ) ) . toBeHidden ( ) ;
1935+ await expect ( page . locator ( "#songDetailsContent #midiImportContent" ) ) . toHaveCount ( 0 ) ;
1936+ await expect ( page . locator ( "#songDetails [data-song-detail-field='sourceMidi']" ) ) . toHaveCount ( 0 ) ;
1937+ await expect ( page . locator ( "#songDetails [data-song-detail-field='instrumentSet']" ) ) . toHaveCount ( 0 ) ;
19201938
1921- const initialSongCount = await page . locator ( "#songList [data-song-id]" ) . count ( ) ;
1922- await page . locator ( "#addSongButton" ) . click ( ) ;
1923- await expect ( page . locator ( "#songList [data-song-id]" ) ) . toHaveCount ( initialSongCount + 1 ) ;
1924- await expect ( page . locator ( "#songList" ) ) . toContainText ( "New Song 4" ) ;
1939+ await page . locator ( "#songDetails [data-song-detail-field='name']" ) . fill ( "Edited UAT Reel" ) ;
1940+ await page . locator ( "#songDetails [data-song-detail-field='id']" ) . fill ( "edited-uat-reel" ) ;
1941+ await page . locator ( "#songSheetTempoInput" ) . fill ( "156" ) ;
1942+ await page . locator ( "#songSheetKeyInput" ) . selectOption ( "C major" ) ;
1943+ await page . locator ( "#songSheetStyleInput" ) . selectOption ( "chip" ) ;
1944+ await page . locator ( "#songDetails [data-song-detail-field='tags']" ) . fill ( "uat, edited" ) ;
1945+ await page . locator ( "#songDetails [data-song-detail-field='usage']" ) . fill ( "title, test" ) ;
1946+ await page . locator ( "#songDetails [data-song-detail-field='notes']" ) . fill ( "Edited notes from Song Setup." ) ;
1947+ await page . locator ( "#songSectionsLoopDetails [data-song-detail-field='loopEnabled']" ) . setChecked ( false ) ;
19251948 expect ( await page . evaluate ( ( ) => {
1926- const app = window . __midiStudioV2App ;
1927- const song = app . selectedSong ( ) ;
1949+ const song = window . __midiStudioV2App . selectedSong ( ) ;
19281950 return {
1929- activeSongId : app . payload . activeSongId ,
1930- hasArrangement : Boolean ( song . studioArrangement ) ,
1931- songCount : app . payload . songs . length
1951+ activeSongId : window . __midiStudioV2App . payload . activeSongId ,
1952+ id : song . id ,
1953+ key : song . studioArrangement . key ,
1954+ loopEnabled : song . loop . enabled ,
1955+ name : song . name ,
1956+ notes : song . director . notes ,
1957+ style : song . studioArrangement . style ,
1958+ tags : song . tags ,
1959+ tempo : song . studioArrangement . tempo ,
1960+ usage : song . director . usage
19321961 } ;
19331962 } ) ) . toEqual ( {
1934- activeSongId : "new-song-4" ,
1935- hasArrangement : true ,
1936- songCount : 4
1963+ activeSongId : "edited-uat-reel" ,
1964+ id : "edited-uat-reel" ,
1965+ key : "C major" ,
1966+ loopEnabled : false ,
1967+ name : "Edited UAT Reel" ,
1968+ notes : "Edited notes from Song Setup." ,
1969+ style : "chip" ,
1970+ tags : [ "uat" , "edited" ] ,
1971+ tempo : "156" ,
1972+ usage : [ "title" , "test" ]
19371973 } ) ;
19381974
1939- await page . locator ( "#songSheetKeyInput" ) . selectOption ( "C major" ) ;
1975+ await page . locator ( '[data-song-id="frog-hop-nursery-rhyme"]' ) . click ( ) ;
1976+ await expect ( page . locator ( "#songDetails [data-song-detail-field='name']" ) ) . toHaveValue ( "Frog Hop Nursery Rhyme UAT" ) ;
1977+ await expect ( page . locator ( "#songDetails [data-song-detail-field='id']" ) ) . toHaveValue ( "frog-hop-nursery-rhyme" ) ;
1978+ await expect ( page . locator ( "#songSheetTempoInput" ) ) . toHaveValue ( "132" ) ;
19401979 await expect ( page . locator ( "#songSheetKeyInput" ) ) . toHaveValue ( "C major" ) ;
1941- await expect . poll ( ( ) => page . evaluate ( ( ) => window . __midiStudioV2App . selectedSong ( ) . studioArrangement . key ) ) . toBe ( "C major" ) ;
1942- await page . locator ( "#songSheetStyleInput" ) . selectOption ( "chip" ) ;
19431980 await expect ( page . locator ( "#songSheetStyleInput" ) ) . toHaveValue ( "chip" ) ;
1944- await expect . poll ( ( ) => page . evaluate ( ( ) => window . __midiStudioV2App . selectedSong ( ) . studioArrangement . style ) ) . toBe ( "chip ") ;
1981+ await expect ( page . locator ( "#songDetails [data-song-detail-field='usage']" ) ) . toHaveValue ( "uat, frog-hop, nursery-rhyme ") ;
19451982
1983+ await selectMidiStudioTab ( page , "instruments" ) ;
1984+ await selectInstrumentRow ( page , "lead" ) ;
19461985 await selectMidiStudioTab ( page , "studio" ) ;
19471986 await waitForCanvasRender ( page ) ;
19481987 await expect ( octaveTimelineCanvas ( page ) ) . toBeVisible ( ) ;
1988+ await clickCanvasCell ( page , "C6" , 2 ) ;
1989+ expect ( await page . evaluate ( ( ) => window . __midiStudioV2App . selectedSong ( ) . studioArrangement . lanes . lead ) ) . toContain ( "C6" ) ;
19491990 await page . locator ( "#playButton" ) . click ( ) ;
19501991 await expect ( page . locator ( "#playButton" ) ) . toBeDisabled ( ) ;
19511992 await expect ( page . locator ( "#stopButton" ) ) . toBeEnabled ( ) ;
19521993 await page . locator ( "#stopButton" ) . click ( ) ;
19531994 await expect ( page . locator ( "#stopButton" ) ) . toBeDisabled ( ) ;
19541995 await expect ( page . locator ( "#playButton" ) ) . toBeEnabled ( ) ;
1955- expect ( await page . evaluate ( ( ) => {
1956- const song = window . __midiStudioV2App . selectedSong ( ) ;
1957- return {
1958- key : song . studioArrangement . key ,
1959- name : song . name ,
1960- style : song . studioArrangement . style
1961- } ;
1962- } ) ) . toEqual ( {
1963- key : "C major" ,
1964- name : "New Song 4" ,
1965- style : "chip"
1966- } ) ;
19671996 } finally {
19681997 await workspaceV2CoverageReporter . stop ( page ) ;
19691998 await server . close ( ) ;
0 commit comments