@@ -26,7 +26,6 @@ const STATUS_HELP_TEXT = Object.freeze({
2626
2727const GAME_JOURNEY_GROUP_ORDER = Object . freeze ( [
2828 "Idea" ,
29- "Create" ,
3029 "Design" ,
3130 "Graphics" ,
3231 "Audio" ,
@@ -42,25 +41,23 @@ const GAME_JOURNEY_GROUP_ORDER = Object.freeze([
4241] ) ;
4342
4443const GAME_JOURNEY_ACCORDION_LABELS = Object . freeze ( [
45- "0% - Idea: Dream, brainstorm, and explore (0 of 4 complete, inactive)" ,
46- "0% - Create: Set up your game and crew (0 of 5 complete, active)" ,
47- "0% - Design: Shape the player experience (0 of 5 complete, active)" ,
48- "0% - Graphics: Create the look of your game (0 of 5 complete, active)" ,
49- "0% - Audio: Bring your world to life with sound (0 of 4 complete, inactive)" ,
50- "0% - Objects: Build things players can interact with (0 of 5 complete, active)" ,
51- "0% - Worlds: Design places to explore (0 of 5 complete, active)" ,
52- "0% - Interface: Create what players see and use (0 of 5 complete, active)" ,
53- "0% - Controls: Define how players play (0 of 4 complete, active)" ,
54- "0% - Rules: Make your game come alive (0 of 5 complete, active)" ,
55- "0% - Progression: Reward players and keep them engaged (0 of 4 complete, inactive)" ,
56- "0% - Play Test: See how your game feels (0 of 5 complete, active)" ,
57- "0% - Publish: Prepare your game for launch (0 of 5 complete, active)" ,
58- "0% - Share: Grow your community (0 of 5 complete, inactive)" ,
44+ "0% Complete — Idea: Dream, brainstorm, and explore" ,
45+ "0% Complete — Design: Shape your game's story and systems" ,
46+ "0% Complete — Graphics: Create the visual look of your game" ,
47+ "0% Complete — Audio: Build sounds, music, and voices" ,
48+ "0% Complete — Objects: Create the things players interact with" ,
49+ "0% Complete — Worlds: Build levels, maps, and places to explore" ,
50+ "0% Complete — Interface: Design menus, HUDs, and player screens" ,
51+ "0% Complete — Controls: Define how players interact with your game" ,
52+ "0% Complete — Rules: Create gameplay behavior and events" ,
53+ "0% Complete — Progression: Build rewards, unlocks, and advancement" ,
54+ "0% Complete — Play Test: Test, debug, and improve your game" ,
55+ "0% Complete — Publish: Prepare and release your game" ,
56+ "0% Complete — Share: Grow your audience and community" ,
5957] ) ;
6058
6159const GAME_JOURNEY_GROUP_COLORS = Object . freeze ( {
6260 "Idea" : { hex : "#FF2D2D" , rgb : "rgb(255, 45, 45)" } ,
63- "Create" : { hex : "#F59E0B" , rgb : "rgb(245, 158, 11)" } ,
6461 "Design" : { hex : "#FF7A00" , rgb : "rgb(255, 122, 0)" } ,
6562 "Graphics" : { hex : "#FFC857" , rgb : "rgb(255, 200, 87)" } ,
6663 "Audio" : { hex : "#FACC15" , rgb : "rgb(250, 204, 21)" } ,
@@ -791,8 +788,11 @@ test("toolbox grouped view renders Game Journey order with unique colors while B
791788 labels . map ( ( label ) => label . textContent . trim ( ) )
792789 ) ) ;
793790 expect ( accordionLabels ) . toEqual ( GAME_JOURNEY_ACCORDION_LABELS ) ;
794- expect ( accordionLabels . every ( ( label ) => / ^ \d + % - . + \( \d + o f \d + c o m p l e t e , ( a c t i v e | i n a c t i v e ) \) $ / . test ( label ) ) ) . toBe ( true ) ;
791+ expect ( accordionLabels . every ( ( label ) => / ^ \d + % C o m p l e t e — . + : . + $ / . test ( label ) ) ) . toBe ( true ) ;
795792 expect ( accordionLabels . join ( " " ) ) . not . toContain ( "xxx%" ) ;
793+ expect ( accordionLabels . join ( " " ) ) . not . toMatch ( / \( \d + o f \d + c o m p l e t e / ) ;
794+ expect ( accordionLabels . join ( " " ) ) . not . toContain ( "inactive" ) ;
795+ expect ( accordionLabels . join ( " " ) ) . not . toContain ( "active" ) ;
796796 expect ( accordionLabels . every ( ( label ) => ! / [ \r \n ] / . test ( label ) ) ) . toBe ( true ) ;
797797
798798 const groupSwatches = await page . locator ( "[data-tools-accordion] > summary [data-toolbox-group-label]" ) . evaluateAll ( ( labels ) => (
@@ -819,19 +819,21 @@ test("toolbox grouped view renders Game Journey order with unique colors while B
819819 expect ( toolboxGroupsByTool [ "Idea Board" ] ) . toBe ( "Idea" ) ;
820820 expect ( toolboxGroupsByTool [ "Creator Learning" ] ) . toBe ( "Idea" ) ;
821821 expect ( toolboxGroupsByTool [ "AI Command Center" ] ) . toBe ( "Design" ) ;
822- expect ( toolboxGroupsByTool [ "Game Hub" ] ) . toBe ( "Create " ) ;
823- expect ( toolboxGroupsByTool [ "Game Configuration" ] ) . toBe ( "Create " ) ;
824- expect ( toolboxGroupsByTool [ "Game Crew" ] ) . toBe ( "Create " ) ;
825- expect ( toolboxGroupsByTool [ "Tags" ] ) . toBe ( "Create " ) ;
822+ expect ( toolboxGroupsByTool [ "Game Hub" ] ) . toBe ( "Design " ) ;
823+ expect ( toolboxGroupsByTool [ "Game Configuration" ] ) . toBe ( "Design " ) ;
824+ expect ( toolboxGroupsByTool [ "Game Crew" ] ) . toBe ( "Design " ) ;
825+ expect ( toolboxGroupsByTool [ "Tags" ] ) . toBe ( "Design " ) ;
826826 expect ( toolboxGroupsByTool [ "Game Journey" ] ) . toBe ( "Progression" ) ;
827827 expect ( toolboxGroupsByTool [ "Publish" ] ) . toBe ( "Publish" ) ;
828828 expect ( toolboxGroupsByTool [ "Marketplace" ] ) . toBe ( "Share" ) ;
829829 expect ( toolboxGroupsByTool . Users ) . toBeUndefined ( ) ;
830830
831- const createToolOrder = await page . locator ( "[data-tools-accordion='Create '] [data-toolbox-tool-card]" ) . evaluateAll ( ( cards ) => (
831+ const designToolOrder = await page . locator ( "[data-tools-accordion='Design '] [data-toolbox-tool-card]" ) . evaluateAll ( ( cards ) => (
832832 cards . map ( ( card ) => card . getAttribute ( "data-toolbox-tool-card" ) )
833833 ) ) ;
834- expect ( createToolOrder ) . toEqual ( [ "Game Hub" , "Game Crew" , "Game Configuration" , "Tags" ] ) ;
834+ const expectedDesignTools = [ "Game Hub" , "Game Crew" , "Game Configuration" , "Tags" , "Game Design" , "AI Command Center" ] ;
835+ expect ( designToolOrder ) . toEqual ( expect . arrayContaining ( expectedDesignTools ) ) ;
836+ expect ( designToolOrder . filter ( ( title ) => expectedDesignTools . includes ( title ) ) ) . toEqual ( expectedDesignTools ) ;
835837
836838 const toolLinks = await page . locator ( "[data-toolbox-tool-name-link]" ) . evaluateAll ( ( links ) => (
837839 links . map ( ( link ) => ( {
@@ -877,6 +879,79 @@ test("toolbox grouped view renders Game Journey order with unique colors while B
877879 }
878880} ) ;
879881
882+ test ( "toolbox grouped Game Journey accordions keep friendly labels readable on mobile" , async ( { page } ) => {
883+ const server = await startRepoServer ( ) ;
884+ const previousApiUrl = process . env . GAMEFOUNDRY_API_URL ;
885+ const previousSiteUrl = process . env . GAMEFOUNDRY_SITE_URL ;
886+ process . env . GAMEFOUNDRY_API_URL = `${ server . baseUrl } /api` ;
887+ process . env . GAMEFOUNDRY_SITE_URL = server . baseUrl ;
888+ const failedRequests = [ ] ;
889+ const pageErrors = [ ] ;
890+ const consoleErrors = [ ] ;
891+
892+ page . on ( "response" , ( response ) => {
893+ if ( response . status ( ) >= 400 ) {
894+ failedRequests . push ( `${ response . status ( ) } ${ response . url ( ) } ` ) ;
895+ }
896+ } ) ;
897+ page . on ( "requestfailed" , ( request ) => {
898+ failedRequests . push ( `FAILED ${ request . url ( ) } ` ) ;
899+ } ) ;
900+ page . on ( "pageerror" , ( error ) => {
901+ const text = error . stack || error . message ;
902+ if ( ! isBrowserExtensionNoise ( text ) ) {
903+ pageErrors . push ( error . message ) ;
904+ }
905+ } ) ;
906+ page . on ( "console" , ( message ) => {
907+ if ( message . type ( ) === "error" && ! isBrowserExtensionNoise ( message . text ( ) ) ) {
908+ consoleErrors . push ( message . text ( ) ) ;
909+ }
910+ } ) ;
911+
912+ try {
913+ await page . setViewportSize ( { width : 390 , height : 844 } ) ;
914+ await workspaceV2CoverageReporter . start ( page ) ;
915+ await setServerSession ( server , MOCK_DB_KEYS . users . admin ) ;
916+ await page . goto ( `${ server . baseUrl } /toolbox/index.html?view=group` , { waitUntil : "networkidle" } ) ;
917+ const plannedFilter = page . locator ( "[data-toolbox-status-filter='planned']" ) ;
918+ if ( await plannedFilter . getAttribute ( "aria-pressed" ) !== "true" ) {
919+ await plannedFilter . click ( ) ;
920+ }
921+ const deprecatedFilter = page . locator ( "[data-toolbox-status-filter='deprecated']" ) ;
922+ if ( await deprecatedFilter . getAttribute ( "aria-pressed" ) !== "true" ) {
923+ await deprecatedFilter . click ( ) ;
924+ }
925+
926+ const labels = page . locator ( "[data-tools-accordion] > summary [data-toolbox-group-label]" ) ;
927+ await expect ( labels ) . toHaveText ( GAME_JOURNEY_ACCORDION_LABELS ) ;
928+ const labelLayout = await labels . evaluateAll ( ( items ) => (
929+ items . map ( ( label ) => {
930+ const rect = label . getBoundingClientRect ( ) ;
931+ const viewportWidth = document . documentElement . clientWidth ;
932+ return {
933+ fitsViewport : rect . left >= 0 && rect . right <= viewportWidth ,
934+ text : label . textContent . trim ( ) ,
935+ wraps : getComputedStyle ( label ) . whiteSpace !== "nowrap" ,
936+ } ;
937+ } )
938+ ) ) ;
939+ expect ( labelLayout . every ( ( item ) => item . fitsViewport ) ) . toBe ( true ) ;
940+ expect ( labelLayout . every ( ( item ) => item . wraps ) ) . toBe ( true ) ;
941+ expect ( labelLayout . map ( ( item ) => item . text ) ) . toEqual ( GAME_JOURNEY_ACCORDION_LABELS ) ;
942+ await expect ( page . locator ( "style, [style], script:not([src])" ) ) . toHaveCount ( 0 ) ;
943+
944+ expect ( failedRequests ) . toEqual ( [ ] ) ;
945+ expect ( pageErrors ) . toEqual ( [ ] ) ;
946+ expect ( consoleErrors ) . toEqual ( [ ] ) ;
947+ } finally {
948+ await workspaceV2CoverageReporter . stop ( page ) ;
949+ await server . close ( ) ;
950+ restoreEnvValue ( "GAMEFOUNDRY_API_URL" , previousApiUrl ) ;
951+ restoreEnvValue ( "GAMEFOUNDRY_SITE_URL" , previousSiteUrl ) ;
952+ }
953+ } ) ;
954+
880955test ( "Game Crew friendly route resolves while old Users route remains compatible" , async ( { page } ) => {
881956 const server = await startRepoServer ( ) ;
882957 const previousApiUrl = process . env . GAMEFOUNDRY_API_URL ;
0 commit comments