diff --git a/.playwright-mcp/page-2026-08-26T11-52-53-592Z.yml b/.playwright-mcp/page-2026-08-26T11-52-53-592Z.yml new file mode 100644 index 0000000..29e6551 --- /dev/null +++ b/.playwright-mcp/page-2026-08-26T11-52-53-592Z.yml @@ -0,0 +1,238 @@ +- generic [active] [ref=e1]: + - banner [ref=e2]: + - generic [ref=e4]: + - button "Toggle menu" [ref=e6] + - link "Tailspin Toys" [ref=e10] [cursor=pointer]: + - /url: / + - main [ref=e11]: + - generic [ref=e13]: + - generic [ref=e14]: + - heading "Welcome to Tailspin Toys" [level=1] [ref=e15] + - paragraph [ref=e16]: Find your next game! And maybe even back one! Explore our collection! + - generic [ref=e17]: + - heading "Filter Games" [level=2] [ref=e18] + - generic [ref=e19]: + - generic [ref=e20]: + - heading "Categories" [level=3] [ref=e21] + - group "Filter by categories" [ref=e22]: + - generic [ref=e23] [cursor=pointer]: + - checkbox "Action" [ref=e24] + - generic [ref=e25]: Action + - generic [ref=e26] [cursor=pointer]: + - checkbox "Adventure" [ref=e27] + - generic [ref=e28]: Adventure + - generic [ref=e29] [cursor=pointer]: + - checkbox "Puzzle" [ref=e30] + - generic [ref=e31]: Puzzle + - generic [ref=e32] [cursor=pointer]: + - checkbox "Simulation" [ref=e33] + - generic [ref=e34]: Simulation + - generic [ref=e35] [cursor=pointer]: + - checkbox "Strategy" [ref=e36] + - generic [ref=e37]: Strategy + - generic [ref=e38]: + - generic [ref=e39]: Publisher + - combobox "Publisher" [ref=e40] [cursor=pointer]: + - option "All Publishers" [selected] + - option "CodeForge Studios" + - option "DevMasters Inc." + - option "GitHub Games" + - option "Ops Interactive" + - button "Reset Filters" [ref=e41] + - generic [ref=e42]: + - heading "Featured Games" [level=2] [ref=e43] + - generic [ref=e44]: + - link "Binary Frontier Adventure DevMasters Inc. Binary Frontier transports you into an uncharted cyber-world where every innovative code unlocks a secret realm. Guided by Mona, explore vast digital landscapes and chart new territories in a narrative steeped in coding mystique. Support this game through our crowdfunding platform! View details" [ref=e45] [cursor=pointer]: + - /url: /game/14 + - generic [ref=e48]: + - heading "Binary Frontier" [level=3] [ref=e49] + - generic [ref=e50]: + - generic [ref=e51]: Adventure + - generic [ref=e52]: DevMasters Inc. + - paragraph [ref=e53]: Binary Frontier transports you into an uncharted cyber-world where every innovative code unlocks a secret realm. Guided by Mona, explore vast digital landscapes and chart new territories in a narrative steeped in coding mystique. Support this game through our crowdfunding platform! + - generic [ref=e54]: View details + - link "Bug Buster Brainteaser Puzzle GitHub Games Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! View details" [ref=e58] [cursor=pointer]: + - /url: /game/7 + - generic [ref=e61]: + - heading "Bug Buster Brainteaser" [level=3] [ref=e62] + - generic [ref=e63]: + - generic [ref=e64]: Puzzle + - generic [ref=e65]: GitHub Games + - paragraph [ref=e66]: Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! + - generic [ref=e67]: View details + - link "Cloud Conqueror Action CodeForge Studios Cloud Conqueror thrusts you into a high-stakes aerial battle against rogue cloud services. With Mona as your co-pilot, navigate through stormy skies and outmaneuver digital adversaries in a quest to reclaim control over your virtual domain. Support this game through our crowdfunding platform! View details" [ref=e71] [cursor=pointer]: + - /url: /game/21 + - generic [ref=e74]: + - heading "Cloud Conqueror" [level=3] [ref=e75] + - generic [ref=e76]: + - generic [ref=e77]: Action + - generic [ref=e78]: CodeForge Studios + - paragraph [ref=e79]: Cloud Conqueror thrusts you into a high-stakes aerial battle against rogue cloud services. With Mona as your co-pilot, navigate through stormy skies and outmaneuver digital adversaries in a quest to reclaim control over your virtual domain. Support this game through our crowdfunding platform! + - generic [ref=e80]: View details + - link "Code Puzzle Chronicles Puzzle CodeForge Studios Code Puzzle Chronicles offers brain-teasing challenges that unravel cryptic algorithms and obscure debugging quests. Mona assists you through each twist, inviting coders to master logic puzzles inspired by real-world coding conundrums. Support this game through our crowdfunding platform! View details" [ref=e84] [cursor=pointer]: + - /url: /game/5 + - generic [ref=e87]: + - heading "Code Puzzle Chronicles" [level=3] [ref=e88] + - generic [ref=e89]: + - generic [ref=e90]: Puzzle + - generic [ref=e91]: CodeForge Studios + - paragraph [ref=e92]: Code Puzzle Chronicles offers brain-teasing challenges that unravel cryptic algorithms and obscure debugging quests. Mona assists you through each twist, inviting coders to master logic puzzles inspired by real-world coding conundrums. Support this game through our crowdfunding platform! + - generic [ref=e93]: View details + - link "Code Quest Odyssey Adventure CodeForge Studios Code Quest Odyssey launches you on an epic journey through enchanted digital realms where coding skills are your passport to discovery. Accompanied by Mona, unravel ancient source codes and conquer challenges that blend narrative with technical ingenuity. Support this game through our crowdfunding platform! View details" [ref=e97] [cursor=pointer]: + - /url: /game/13 + - generic [ref=e100]: + - heading "Code Quest Odyssey" [level=3] [ref=e101] + - generic [ref=e102]: + - generic [ref=e103]: Adventure + - generic [ref=e104]: CodeForge Studios + - paragraph [ref=e105]: Code Quest Odyssey launches you on an epic journey through enchanted digital realms where coding skills are your passport to discovery. Accompanied by Mona, unravel ancient source codes and conquer challenges that blend narrative with technical ingenuity. Support this game through our crowdfunding platform! + - generic [ref=e106]: View details + - link "Container Chaos Simulation DevMasters Inc. Container Chaos replicates the high-stakes environment of container orchestration where every command can either streamline or disrupt your systems. Mona's expert advice will help you navigate the wild world of Docker containers and scalable cloud services. Support this game through our crowdfunding platform! View details" [ref=e110] [cursor=pointer]: + - /url: /game/10 + - generic [ref=e113]: + - heading "Container Chaos" [level=3] [ref=e114] + - generic [ref=e115]: + - generic [ref=e116]: Simulation + - generic [ref=e117]: DevMasters Inc. + - paragraph [ref=e118]: Container Chaos replicates the high-stakes environment of container orchestration where every command can either streamline or disrupt your systems. Mona's expert advice will help you navigate the wild world of Docker containers and scalable cloud services. Support this game through our crowdfunding platform! + - generic [ref=e119]: View details + - link "Deployment Dynasty Simulation Ops Interactive Deployment Dynasty enables you to craft and manage digital empires across complex simulated environments. Mona lends her expertise to help you master scaling, monitoring, and auto-healing routines to maintain your virtual dominion. Support this game through our crowdfunding platform! View details" [ref=e123] [cursor=pointer]: + - /url: /game/12 + - generic [ref=e126]: + - heading "Deployment Dynasty" [level=3] [ref=e127] + - generic [ref=e128]: + - generic [ref=e129]: Simulation + - generic [ref=e130]: Ops Interactive + - paragraph [ref=e131]: Deployment Dynasty enables you to craft and manage digital empires across complex simulated environments. Mona lends her expertise to help you master scaling, monitoring, and auto-healing routines to maintain your virtual dominion. Support this game through our crowdfunding platform! + - generic [ref=e132]: View details + - link "DevOps Dominion Strategy CodeForge Studios In DevOps Dominion, strategic planning meets advanced deployment tactics in a fast-paced battlefield of code. Mona leads your team of digital warriors through orchestrated pipelines and microservice skirmishes, ensuring every command brings a competitive edge. Support this game through our crowdfunding platform! View details" [ref=e136] [cursor=pointer]: + - /url: /game/1 + - generic [ref=e139]: + - heading "DevOps Dominion" [level=3] [ref=e140] + - generic [ref=e141]: + - generic [ref=e142]: Strategy + - generic [ref=e143]: CodeForge Studios + - paragraph [ref=e144]: In DevOps Dominion, strategic planning meets advanced deployment tactics in a fast-paced battlefield of code. Mona leads your team of digital warriors through orchestrated pipelines and microservice skirmishes, ensuring every command brings a competitive edge. Support this game through our crowdfunding platform! + - generic [ref=e145]: View details + - link "Digital Debugger's Dream Adventure GitHub Games Digital Debugger's Dream pioneers an immersive adventure that merges investigative quests with real-life debugging scenarios. As Mona champions your journey, each step deepens the mystery behind a cybernetic riddle waiting to be resolved. Support this game through our crowdfunding platform! View details" [ref=e149] [cursor=pointer]: + - /url: /game/15 + - generic [ref=e152]: + - heading "Digital Debugger's Dream" [level=3] [ref=e153] + - generic [ref=e154]: + - generic [ref=e155]: Adventure + - generic [ref=e156]: GitHub Games + - paragraph [ref=e157]: Digital Debugger's Dream pioneers an immersive adventure that merges investigative quests with real-life debugging scenarios. As Mona champions your journey, each step deepens the mystery behind a cybernetic riddle waiting to be resolved. Support this game through our crowdfunding platform! + - generic [ref=e158]: View details + - link "Infrastructure Innovator Simulation GitHub Games Infrastructure Innovator simulates a sprawling digital ecosystem that challenges you to build robust networks from scratch. With Mona’s strategic tips, you’ll design and implement systems that stand up to relentless virtual stress tests. Support this game through our crowdfunding platform! View details" [ref=e162] [cursor=pointer]: + - /url: /game/11 + - generic [ref=e165]: + - heading "Infrastructure Innovator" [level=3] [ref=e166] + - generic [ref=e167]: + - generic [ref=e168]: Simulation + - generic [ref=e169]: GitHub Games + - paragraph [ref=e170]: Infrastructure Innovator simulates a sprawling digital ecosystem that challenges you to build robust networks from scratch. With Mona’s strategic tips, you’ll design and implement systems that stand up to relentless virtual stress tests. Support this game through our crowdfunding platform! + - generic [ref=e171]: View details + - link "Merge Conflict Mystery Puzzle DevMasters Inc. Merge Conflict Mystery immerses you in a labyrinth of code merges where every puzzle piece is a potential breakthrough. With Mona helping decode errors, your task is to resolve conflicts and streamline integration across complex code branches. Support this game through our crowdfunding platform! View details" [ref=e175] [cursor=pointer]: + - /url: /game/6 + - generic [ref=e178]: + - heading "Merge Conflict Mystery" [level=3] [ref=e179] + - generic [ref=e180]: + - generic [ref=e181]: Puzzle + - generic [ref=e182]: DevMasters Inc. + - paragraph [ref=e183]: Merge Conflict Mystery immerses you in a labyrinth of code merges where every puzzle piece is a potential breakthrough. With Mona helping decode errors, your task is to resolve conflicts and streamline integration across complex code branches. Support this game through our crowdfunding platform! + - generic [ref=e184]: View details + - link "Pipeline Conquest Strategy DevMasters Inc. Pipeline Conquest challenges players to optimize continuous integration workflows while countering unforeseen system failures. With Mona by your side, organize automated builds and deployment pipelines in real time to secure lasting digital victory. Support this game through our crowdfunding platform! View details" [ref=e188] [cursor=pointer]: + - /url: /game/2 + - generic [ref=e191]: + - heading "Pipeline Conquest" [level=3] [ref=e192] + - generic [ref=e193]: + - generic [ref=e194]: Strategy + - generic [ref=e195]: DevMasters Inc. + - paragraph [ref=e196]: Pipeline Conquest challenges players to optimize continuous integration workflows while countering unforeseen system failures. With Mona by your side, organize automated builds and deployment pipelines in real time to secure lasting digital victory. Support this game through our crowdfunding platform! + - generic [ref=e197]: View details + - link "Refactor Realms Adventure Ops Interactive Refactor Realms beckons you into a world where systematic code improvement reshapes ancient digital civilizations. With Mona’s mentorship, transform legacy systems into streamlined masterpieces as you explore breathtaking virtual environments. Support this game through our crowdfunding platform! View details" [ref=e201] [cursor=pointer]: + - /url: /game/16 + - generic [ref=e204]: + - heading "Refactor Realms" [level=3] [ref=e205] + - generic [ref=e206]: + - generic [ref=e207]: Adventure + - generic [ref=e208]: Ops Interactive + - paragraph [ref=e209]: Refactor Realms beckons you into a world where systematic code improvement reshapes ancient digital civilizations. With Mona’s mentorship, transform legacy systems into streamlined masterpieces as you explore breathtaking virtual environments. Support this game through our crowdfunding platform! + - generic [ref=e210]: View details + - link "Repo Rampart Action GitHub Games Repo Rampart immerses you in adrenaline-charged defense missions where every command must protect your precious codebases. With Mona leading your strategy, prevent intrusions and execute swift countermeasures in electrifying action sequences. Support this game through our crowdfunding platform! View details" [ref=e214] [cursor=pointer]: + - /url: /game/19 + - generic [ref=e217]: + - heading "Repo Rampart" [level=3] [ref=e218] + - generic [ref=e219]: + - generic [ref=e220]: Action + - generic [ref=e221]: GitHub Games + - paragraph [ref=e222]: Repo Rampart immerses you in adrenaline-charged defense missions where every command must protect your precious codebases. With Mona leading your strategy, prevent intrusions and execute swift countermeasures in electrifying action sequences. Support this game through our crowdfunding platform! + - generic [ref=e223]: View details + - link "Repo Rulers Strategy Ops Interactive Repo Rulers demands razor-sharp tactics and agile repository management to dominate interconnected servers. Under Mona’s guidance, you'll enforce branch protections and manage pull requests in a high-stakes arena where precision is paramount. Support this game through our crowdfunding platform! View details" [ref=e227] [cursor=pointer]: + - /url: /game/4 + - generic [ref=e230]: + - heading "Repo Rulers" [level=3] [ref=e231] + - generic [ref=e232]: + - generic [ref=e233]: Strategy + - generic [ref=e234]: Ops Interactive + - paragraph [ref=e235]: Repo Rulers demands razor-sharp tactics and agile repository management to dominate interconnected servers. Under Mona’s guidance, you'll enforce branch protections and manage pull requests in a high-stakes arena where precision is paramount. Support this game through our crowdfunding platform! + - generic [ref=e236]: View details + - link "Script Strike Action CodeForge Studios Script Strike propels you into a fast-paced coding battleground where every keystroke could change the tide of an intense conflict. Mona rallies your forces as you dive into real-time challenges that merge reflexes with smart script execution. Support this game through our crowdfunding platform! View details" [ref=e240] [cursor=pointer]: + - /url: /game/17 + - generic [ref=e243]: + - heading "Script Strike" [level=3] [ref=e244] + - generic [ref=e245]: + - generic [ref=e246]: Action + - generic [ref=e247]: CodeForge Studios + - paragraph [ref=e248]: Script Strike propels you into a fast-paced coding battleground where every keystroke could change the tide of an intense conflict. Mona rallies your forces as you dive into real-time challenges that merge reflexes with smart script execution. Support this game through our crowdfunding platform! + - generic [ref=e249]: View details + - link "Server Siege Strategy GitHub Games Server Siege throws you into the midst of a digital fortress under siege by relentless cyber threats. As Mona rallies your defense, you'll coordinate load-balancers and version controls to fortify your network stronghold. Support this game through our crowdfunding platform! View details" [ref=e253] [cursor=pointer]: + - /url: /game/3 + - generic [ref=e256]: + - heading "Server Siege" [level=3] [ref=e257] + - generic [ref=e258]: + - generic [ref=e259]: Strategy + - generic [ref=e260]: GitHub Games + - paragraph [ref=e261]: Server Siege throws you into the midst of a digital fortress under siege by relentless cyber threats. As Mona rallies your defense, you'll coordinate load-balancers and version controls to fortify your network stronghold. Support this game through our crowdfunding platform! + - generic [ref=e262]: View details + - link "Stack Trace Secrets Puzzle Ops Interactive Stack Trace Secrets invites you to decrypt layered error logs and reveal hidden insights within your code. With guidance from Mona, every error message becomes a clue in the puzzle of perfecting your software architecture. Support this game through our crowdfunding platform! View details" [ref=e266] [cursor=pointer]: + - /url: /game/8 + - generic [ref=e269]: + - heading "Stack Trace Secrets" [level=3] [ref=e270] + - generic [ref=e271]: + - generic [ref=e272]: Puzzle + - generic [ref=e273]: Ops Interactive + - paragraph [ref=e274]: Stack Trace Secrets invites you to decrypt layered error logs and reveal hidden insights within your code. With guidance from Mona, every error message becomes a clue in the puzzle of perfecting your software architecture. Support this game through our crowdfunding platform! + - generic [ref=e275]: View details + - link "Syntax Smashdown Action Ops Interactive Syntax Smashdown offers an exhilarating arcade experience where rapid coding reflexes determine the outcome of explosive digital battles. Guided by the fearless Mona, your mission is to knock out glitches and secure the high-score in a realm where syntax is the ultimate weapon. Support this game through our crowdfunding platform! View details" [ref=e279] [cursor=pointer]: + - /url: /game/20 + - generic [ref=e282]: + - heading "Syntax Smashdown" [level=3] [ref=e283] + - generic [ref=e284]: + - generic [ref=e285]: Action + - generic [ref=e286]: Ops Interactive + - paragraph [ref=e287]: Syntax Smashdown offers an exhilarating arcade experience where rapid coding reflexes determine the outcome of explosive digital battles. Guided by the fearless Mona, your mission is to knock out glitches and secure the high-score in a realm where syntax is the ultimate weapon. Support this game through our crowdfunding platform! + - generic [ref=e288]: View details + - link "Terminal Turbulence Action DevMasters Inc. Terminal Turbulence pits you against rapid-fire command line confrontations where timing and precision are of the essence. Let Mona’s digital savvy guide your response strategies as you navigate chaotic server environments in high-octane style. Support this game through our crowdfunding platform! View details" [ref=e292] [cursor=pointer]: + - /url: /game/18 + - generic [ref=e295]: + - heading "Terminal Turbulence" [level=3] [ref=e296] + - generic [ref=e297]: + - generic [ref=e298]: Action + - generic [ref=e299]: DevMasters Inc. + - paragraph [ref=e300]: Terminal Turbulence pits you against rapid-fire command line confrontations where timing and precision are of the essence. Let Mona’s digital savvy guide your response strategies as you navigate chaotic server environments in high-octane style. Support this game through our crowdfunding platform! + - generic [ref=e301]: View details + - link "Virtual Server Simulator Simulation CodeForge Studios Virtual Server Simulator places you in a hyper-realistic data center where resource management is the key to survival. Mona guides you as you balance load distributions and optimize server performance in a dynamic virtual ecosystem. Support this game through our crowdfunding platform! View details" [ref=e305] [cursor=pointer]: + - /url: /game/9 + - generic [ref=e308]: + - heading "Virtual Server Simulator" [level=3] [ref=e309] + - generic [ref=e310]: + - generic [ref=e311]: Simulation + - generic [ref=e312]: CodeForge Studios + - paragraph [ref=e313]: Virtual Server Simulator places you in a hyper-realistic data center where resource management is the key to survival. Mona guides you as you balance load distributions and optimize server performance in a dynamic virtual ecosystem. Support this game through our crowdfunding platform! + - generic [ref=e314]: View details + - generic [ref=e320]: + - button [ref=e321] + - button [ref=e327] + - button [ref=e331] + - button [ref=e336] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-08-26T11-53-47-330Z.yml b/.playwright-mcp/page-2026-08-26T11-53-47-330Z.yml new file mode 100644 index 0000000..2c44fe0 --- /dev/null +++ b/.playwright-mcp/page-2026-08-26T11-53-47-330Z.yml @@ -0,0 +1,85 @@ +- generic [ref=e1]: + - banner [ref=e2]: + - generic [ref=e4]: + - button "Toggle menu" [ref=e6] + - link "Tailspin Toys" [ref=e10] [cursor=pointer]: + - /url: / + - main [ref=e11]: + - generic [ref=e13]: + - generic [ref=e14]: + - heading "Welcome to Tailspin Toys" [level=1] [ref=e15] + - paragraph [ref=e16]: Find your next game! And maybe even back one! Explore our collection! + - generic [ref=e17]: + - heading "Filter Games" [level=2] [ref=e18] + - generic [ref=e19]: + - generic [ref=e20]: + - heading "Categories" [level=3] [ref=e21] + - group "Filter by categories" [ref=e22]: + - generic [ref=e23] [cursor=pointer]: + - checkbox "Action" [ref=e24] + - generic [ref=e25]: Action + - generic [ref=e26] [cursor=pointer]: + - checkbox "Adventure" [ref=e27] + - generic [ref=e28]: Adventure + - generic [ref=e29] [cursor=pointer]: + - checkbox "Puzzle" [checked] [active] [ref=e30] + - generic [ref=e31]: Puzzle + - generic [ref=e32] [cursor=pointer]: + - checkbox "Simulation" [ref=e33] + - generic [ref=e34]: Simulation + - generic [ref=e35] [cursor=pointer]: + - checkbox "Strategy" [ref=e36] + - generic [ref=e37]: Strategy + - generic [ref=e38]: + - generic [ref=e39]: Publisher + - combobox "Publisher" [ref=e40] [cursor=pointer]: + - option "All Publishers" [selected] + - option "CodeForge Studios" + - option "DevMasters Inc." + - option "GitHub Games" + - option "Ops Interactive" + - button "Reset Filters" [ref=e41] + - generic [ref=e42]: + - heading "Featured Games" [level=2] [ref=e43] + - generic [ref=e44]: + - link "Bug Buster Brainteaser Puzzle GitHub Games Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! View details" [ref=e58] [cursor=pointer]: + - /url: /game/7 + - generic [ref=e61]: + - heading "Bug Buster Brainteaser" [level=3] [ref=e62] + - generic [ref=e63]: + - generic [ref=e64]: Puzzle + - generic [ref=e65]: GitHub Games + - paragraph [ref=e66]: Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! + - generic [ref=e67]: View details + - link "Code Puzzle Chronicles Puzzle CodeForge Studios Code Puzzle Chronicles offers brain-teasing challenges that unravel cryptic algorithms and obscure debugging quests. Mona assists you through each twist, inviting coders to master logic puzzles inspired by real-world coding conundrums. Support this game through our crowdfunding platform! View details" [ref=e84] [cursor=pointer]: + - /url: /game/5 + - generic [ref=e87]: + - heading "Code Puzzle Chronicles" [level=3] [ref=e88] + - generic [ref=e89]: + - generic [ref=e90]: Puzzle + - generic [ref=e91]: CodeForge Studios + - paragraph [ref=e92]: Code Puzzle Chronicles offers brain-teasing challenges that unravel cryptic algorithms and obscure debugging quests. Mona assists you through each twist, inviting coders to master logic puzzles inspired by real-world coding conundrums. Support this game through our crowdfunding platform! + - generic [ref=e93]: View details + - link "Merge Conflict Mystery Puzzle DevMasters Inc. Merge Conflict Mystery immerses you in a labyrinth of code merges where every puzzle piece is a potential breakthrough. With Mona helping decode errors, your task is to resolve conflicts and streamline integration across complex code branches. Support this game through our crowdfunding platform! View details" [ref=e175] [cursor=pointer]: + - /url: /game/6 + - generic [ref=e178]: + - heading "Merge Conflict Mystery" [level=3] [ref=e179] + - generic [ref=e180]: + - generic [ref=e181]: Puzzle + - generic [ref=e182]: DevMasters Inc. + - paragraph [ref=e183]: Merge Conflict Mystery immerses you in a labyrinth of code merges where every puzzle piece is a potential breakthrough. With Mona helping decode errors, your task is to resolve conflicts and streamline integration across complex code branches. Support this game through our crowdfunding platform! + - generic [ref=e184]: View details + - link "Stack Trace Secrets Puzzle Ops Interactive Stack Trace Secrets invites you to decrypt layered error logs and reveal hidden insights within your code. With guidance from Mona, every error message becomes a clue in the puzzle of perfecting your software architecture. Support this game through our crowdfunding platform! View details" [ref=e266] [cursor=pointer]: + - /url: /game/8 + - generic [ref=e269]: + - heading "Stack Trace Secrets" [level=3] [ref=e270] + - generic [ref=e271]: + - generic [ref=e272]: Puzzle + - generic [ref=e273]: Ops Interactive + - paragraph [ref=e274]: Stack Trace Secrets invites you to decrypt layered error logs and reveal hidden insights within your code. With guidance from Mona, every error message becomes a clue in the puzzle of perfecting your software architecture. Support this game through our crowdfunding platform! + - generic [ref=e275]: View details + - generic [ref=e320]: + - button [ref=e321] + - button [ref=e327] + - button [ref=e331] + - button [ref=e336] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-08-26T11-54-16-587Z.yml b/.playwright-mcp/page-2026-08-26T11-54-16-587Z.yml new file mode 100644 index 0000000..6904fec --- /dev/null +++ b/.playwright-mcp/page-2026-08-26T11-54-16-587Z.yml @@ -0,0 +1,238 @@ +- generic [ref=e1]: + - banner [ref=e2]: + - generic [ref=e4]: + - button "Toggle menu" [ref=e6] + - link "Tailspin Toys" [ref=e10] [cursor=pointer]: + - /url: / + - main [ref=e11]: + - generic [ref=e13]: + - generic [ref=e14]: + - heading "Welcome to Tailspin Toys" [level=1] [ref=e15] + - paragraph [ref=e16]: Find your next game! And maybe even back one! Explore our collection! + - generic [ref=e17]: + - heading "Filter Games" [level=2] [ref=e18] + - generic [ref=e19]: + - generic [ref=e20]: + - heading "Categories" [level=3] [ref=e21] + - group "Filter by categories" [ref=e22]: + - generic [ref=e23] [cursor=pointer]: + - checkbox "Action" [ref=e24] + - generic [ref=e25]: Action + - generic [ref=e26] [cursor=pointer]: + - checkbox "Adventure" [ref=e27] + - generic [ref=e28]: Adventure + - generic [ref=e29] [cursor=pointer]: + - checkbox "Puzzle" [ref=e30] + - generic [ref=e31]: Puzzle + - generic [ref=e32] [cursor=pointer]: + - checkbox "Simulation" [ref=e33] + - generic [ref=e34]: Simulation + - generic [ref=e35] [cursor=pointer]: + - checkbox "Strategy" [ref=e36] + - generic [ref=e37]: Strategy + - generic [ref=e38]: + - generic [ref=e39]: Publisher + - combobox "Publisher" [ref=e40] [cursor=pointer]: + - option "All Publishers" [selected] + - option "CodeForge Studios" + - option "DevMasters Inc." + - option "GitHub Games" + - option "Ops Interactive" + - button "Reset Filters" [active] [ref=e41] + - generic [ref=e42]: + - heading "Featured Games" [level=2] [ref=e43] + - generic [ref=e44]: + - link "Binary Frontier Adventure DevMasters Inc. Binary Frontier transports you into an uncharted cyber-world where every innovative code unlocks a secret realm. Guided by Mona, explore vast digital landscapes and chart new territories in a narrative steeped in coding mystique. Support this game through our crowdfunding platform! View details" [ref=e45] [cursor=pointer]: + - /url: /game/14 + - generic [ref=e48]: + - heading "Binary Frontier" [level=3] [ref=e49] + - generic [ref=e50]: + - generic [ref=e51]: Adventure + - generic [ref=e52]: DevMasters Inc. + - paragraph [ref=e53]: Binary Frontier transports you into an uncharted cyber-world where every innovative code unlocks a secret realm. Guided by Mona, explore vast digital landscapes and chart new territories in a narrative steeped in coding mystique. Support this game through our crowdfunding platform! + - generic [ref=e54]: View details + - link "Bug Buster Brainteaser Puzzle GitHub Games Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! View details" [ref=e58] [cursor=pointer]: + - /url: /game/7 + - generic [ref=e61]: + - heading "Bug Buster Brainteaser" [level=3] [ref=e62] + - generic [ref=e63]: + - generic [ref=e64]: Puzzle + - generic [ref=e65]: GitHub Games + - paragraph [ref=e66]: Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! + - generic [ref=e67]: View details + - link "Cloud Conqueror Action CodeForge Studios Cloud Conqueror thrusts you into a high-stakes aerial battle against rogue cloud services. With Mona as your co-pilot, navigate through stormy skies and outmaneuver digital adversaries in a quest to reclaim control over your virtual domain. Support this game through our crowdfunding platform! View details" [ref=e71] [cursor=pointer]: + - /url: /game/21 + - generic [ref=e74]: + - heading "Cloud Conqueror" [level=3] [ref=e75] + - generic [ref=e76]: + - generic [ref=e77]: Action + - generic [ref=e78]: CodeForge Studios + - paragraph [ref=e79]: Cloud Conqueror thrusts you into a high-stakes aerial battle against rogue cloud services. With Mona as your co-pilot, navigate through stormy skies and outmaneuver digital adversaries in a quest to reclaim control over your virtual domain. Support this game through our crowdfunding platform! + - generic [ref=e80]: View details + - link "Code Puzzle Chronicles Puzzle CodeForge Studios Code Puzzle Chronicles offers brain-teasing challenges that unravel cryptic algorithms and obscure debugging quests. Mona assists you through each twist, inviting coders to master logic puzzles inspired by real-world coding conundrums. Support this game through our crowdfunding platform! View details" [ref=e84] [cursor=pointer]: + - /url: /game/5 + - generic [ref=e87]: + - heading "Code Puzzle Chronicles" [level=3] [ref=e88] + - generic [ref=e89]: + - generic [ref=e90]: Puzzle + - generic [ref=e91]: CodeForge Studios + - paragraph [ref=e92]: Code Puzzle Chronicles offers brain-teasing challenges that unravel cryptic algorithms and obscure debugging quests. Mona assists you through each twist, inviting coders to master logic puzzles inspired by real-world coding conundrums. Support this game through our crowdfunding platform! + - generic [ref=e93]: View details + - link "Code Quest Odyssey Adventure CodeForge Studios Code Quest Odyssey launches you on an epic journey through enchanted digital realms where coding skills are your passport to discovery. Accompanied by Mona, unravel ancient source codes and conquer challenges that blend narrative with technical ingenuity. Support this game through our crowdfunding platform! View details" [ref=e97] [cursor=pointer]: + - /url: /game/13 + - generic [ref=e100]: + - heading "Code Quest Odyssey" [level=3] [ref=e101] + - generic [ref=e102]: + - generic [ref=e103]: Adventure + - generic [ref=e104]: CodeForge Studios + - paragraph [ref=e105]: Code Quest Odyssey launches you on an epic journey through enchanted digital realms where coding skills are your passport to discovery. Accompanied by Mona, unravel ancient source codes and conquer challenges that blend narrative with technical ingenuity. Support this game through our crowdfunding platform! + - generic [ref=e106]: View details + - link "Container Chaos Simulation DevMasters Inc. Container Chaos replicates the high-stakes environment of container orchestration where every command can either streamline or disrupt your systems. Mona's expert advice will help you navigate the wild world of Docker containers and scalable cloud services. Support this game through our crowdfunding platform! View details" [ref=e110] [cursor=pointer]: + - /url: /game/10 + - generic [ref=e113]: + - heading "Container Chaos" [level=3] [ref=e114] + - generic [ref=e115]: + - generic [ref=e116]: Simulation + - generic [ref=e117]: DevMasters Inc. + - paragraph [ref=e118]: Container Chaos replicates the high-stakes environment of container orchestration where every command can either streamline or disrupt your systems. Mona's expert advice will help you navigate the wild world of Docker containers and scalable cloud services. Support this game through our crowdfunding platform! + - generic [ref=e119]: View details + - link "Deployment Dynasty Simulation Ops Interactive Deployment Dynasty enables you to craft and manage digital empires across complex simulated environments. Mona lends her expertise to help you master scaling, monitoring, and auto-healing routines to maintain your virtual dominion. Support this game through our crowdfunding platform! View details" [ref=e123] [cursor=pointer]: + - /url: /game/12 + - generic [ref=e126]: + - heading "Deployment Dynasty" [level=3] [ref=e127] + - generic [ref=e128]: + - generic [ref=e129]: Simulation + - generic [ref=e130]: Ops Interactive + - paragraph [ref=e131]: Deployment Dynasty enables you to craft and manage digital empires across complex simulated environments. Mona lends her expertise to help you master scaling, monitoring, and auto-healing routines to maintain your virtual dominion. Support this game through our crowdfunding platform! + - generic [ref=e132]: View details + - link "DevOps Dominion Strategy CodeForge Studios In DevOps Dominion, strategic planning meets advanced deployment tactics in a fast-paced battlefield of code. Mona leads your team of digital warriors through orchestrated pipelines and microservice skirmishes, ensuring every command brings a competitive edge. Support this game through our crowdfunding platform! View details" [ref=e136] [cursor=pointer]: + - /url: /game/1 + - generic [ref=e139]: + - heading "DevOps Dominion" [level=3] [ref=e140] + - generic [ref=e141]: + - generic [ref=e142]: Strategy + - generic [ref=e143]: CodeForge Studios + - paragraph [ref=e144]: In DevOps Dominion, strategic planning meets advanced deployment tactics in a fast-paced battlefield of code. Mona leads your team of digital warriors through orchestrated pipelines and microservice skirmishes, ensuring every command brings a competitive edge. Support this game through our crowdfunding platform! + - generic [ref=e145]: View details + - link "Digital Debugger's Dream Adventure GitHub Games Digital Debugger's Dream pioneers an immersive adventure that merges investigative quests with real-life debugging scenarios. As Mona champions your journey, each step deepens the mystery behind a cybernetic riddle waiting to be resolved. Support this game through our crowdfunding platform! View details" [ref=e149] [cursor=pointer]: + - /url: /game/15 + - generic [ref=e152]: + - heading "Digital Debugger's Dream" [level=3] [ref=e153] + - generic [ref=e154]: + - generic [ref=e155]: Adventure + - generic [ref=e156]: GitHub Games + - paragraph [ref=e157]: Digital Debugger's Dream pioneers an immersive adventure that merges investigative quests with real-life debugging scenarios. As Mona champions your journey, each step deepens the mystery behind a cybernetic riddle waiting to be resolved. Support this game through our crowdfunding platform! + - generic [ref=e158]: View details + - link "Infrastructure Innovator Simulation GitHub Games Infrastructure Innovator simulates a sprawling digital ecosystem that challenges you to build robust networks from scratch. With Mona’s strategic tips, you’ll design and implement systems that stand up to relentless virtual stress tests. Support this game through our crowdfunding platform! View details" [ref=e162] [cursor=pointer]: + - /url: /game/11 + - generic [ref=e165]: + - heading "Infrastructure Innovator" [level=3] [ref=e166] + - generic [ref=e167]: + - generic [ref=e168]: Simulation + - generic [ref=e169]: GitHub Games + - paragraph [ref=e170]: Infrastructure Innovator simulates a sprawling digital ecosystem that challenges you to build robust networks from scratch. With Mona’s strategic tips, you’ll design and implement systems that stand up to relentless virtual stress tests. Support this game through our crowdfunding platform! + - generic [ref=e171]: View details + - link "Merge Conflict Mystery Puzzle DevMasters Inc. Merge Conflict Mystery immerses you in a labyrinth of code merges where every puzzle piece is a potential breakthrough. With Mona helping decode errors, your task is to resolve conflicts and streamline integration across complex code branches. Support this game through our crowdfunding platform! View details" [ref=e175] [cursor=pointer]: + - /url: /game/6 + - generic [ref=e178]: + - heading "Merge Conflict Mystery" [level=3] [ref=e179] + - generic [ref=e180]: + - generic [ref=e181]: Puzzle + - generic [ref=e182]: DevMasters Inc. + - paragraph [ref=e183]: Merge Conflict Mystery immerses you in a labyrinth of code merges where every puzzle piece is a potential breakthrough. With Mona helping decode errors, your task is to resolve conflicts and streamline integration across complex code branches. Support this game through our crowdfunding platform! + - generic [ref=e184]: View details + - link "Pipeline Conquest Strategy DevMasters Inc. Pipeline Conquest challenges players to optimize continuous integration workflows while countering unforeseen system failures. With Mona by your side, organize automated builds and deployment pipelines in real time to secure lasting digital victory. Support this game through our crowdfunding platform! View details" [ref=e188] [cursor=pointer]: + - /url: /game/2 + - generic [ref=e191]: + - heading "Pipeline Conquest" [level=3] [ref=e192] + - generic [ref=e193]: + - generic [ref=e194]: Strategy + - generic [ref=e195]: DevMasters Inc. + - paragraph [ref=e196]: Pipeline Conquest challenges players to optimize continuous integration workflows while countering unforeseen system failures. With Mona by your side, organize automated builds and deployment pipelines in real time to secure lasting digital victory. Support this game through our crowdfunding platform! + - generic [ref=e197]: View details + - link "Refactor Realms Adventure Ops Interactive Refactor Realms beckons you into a world where systematic code improvement reshapes ancient digital civilizations. With Mona’s mentorship, transform legacy systems into streamlined masterpieces as you explore breathtaking virtual environments. Support this game through our crowdfunding platform! View details" [ref=e201] [cursor=pointer]: + - /url: /game/16 + - generic [ref=e204]: + - heading "Refactor Realms" [level=3] [ref=e205] + - generic [ref=e206]: + - generic [ref=e207]: Adventure + - generic [ref=e208]: Ops Interactive + - paragraph [ref=e209]: Refactor Realms beckons you into a world where systematic code improvement reshapes ancient digital civilizations. With Mona’s mentorship, transform legacy systems into streamlined masterpieces as you explore breathtaking virtual environments. Support this game through our crowdfunding platform! + - generic [ref=e210]: View details + - link "Repo Rampart Action GitHub Games Repo Rampart immerses you in adrenaline-charged defense missions where every command must protect your precious codebases. With Mona leading your strategy, prevent intrusions and execute swift countermeasures in electrifying action sequences. Support this game through our crowdfunding platform! View details" [ref=e214] [cursor=pointer]: + - /url: /game/19 + - generic [ref=e217]: + - heading "Repo Rampart" [level=3] [ref=e218] + - generic [ref=e219]: + - generic [ref=e220]: Action + - generic [ref=e221]: GitHub Games + - paragraph [ref=e222]: Repo Rampart immerses you in adrenaline-charged defense missions where every command must protect your precious codebases. With Mona leading your strategy, prevent intrusions and execute swift countermeasures in electrifying action sequences. Support this game through our crowdfunding platform! + - generic [ref=e223]: View details + - link "Repo Rulers Strategy Ops Interactive Repo Rulers demands razor-sharp tactics and agile repository management to dominate interconnected servers. Under Mona’s guidance, you'll enforce branch protections and manage pull requests in a high-stakes arena where precision is paramount. Support this game through our crowdfunding platform! View details" [ref=e227] [cursor=pointer]: + - /url: /game/4 + - generic [ref=e230]: + - heading "Repo Rulers" [level=3] [ref=e231] + - generic [ref=e232]: + - generic [ref=e233]: Strategy + - generic [ref=e234]: Ops Interactive + - paragraph [ref=e235]: Repo Rulers demands razor-sharp tactics and agile repository management to dominate interconnected servers. Under Mona’s guidance, you'll enforce branch protections and manage pull requests in a high-stakes arena where precision is paramount. Support this game through our crowdfunding platform! + - generic [ref=e236]: View details + - link "Script Strike Action CodeForge Studios Script Strike propels you into a fast-paced coding battleground where every keystroke could change the tide of an intense conflict. Mona rallies your forces as you dive into real-time challenges that merge reflexes with smart script execution. Support this game through our crowdfunding platform! View details" [ref=e240] [cursor=pointer]: + - /url: /game/17 + - generic [ref=e243]: + - heading "Script Strike" [level=3] [ref=e244] + - generic [ref=e245]: + - generic [ref=e246]: Action + - generic [ref=e247]: CodeForge Studios + - paragraph [ref=e248]: Script Strike propels you into a fast-paced coding battleground where every keystroke could change the tide of an intense conflict. Mona rallies your forces as you dive into real-time challenges that merge reflexes with smart script execution. Support this game through our crowdfunding platform! + - generic [ref=e249]: View details + - link "Server Siege Strategy GitHub Games Server Siege throws you into the midst of a digital fortress under siege by relentless cyber threats. As Mona rallies your defense, you'll coordinate load-balancers and version controls to fortify your network stronghold. Support this game through our crowdfunding platform! View details" [ref=e253] [cursor=pointer]: + - /url: /game/3 + - generic [ref=e256]: + - heading "Server Siege" [level=3] [ref=e257] + - generic [ref=e258]: + - generic [ref=e259]: Strategy + - generic [ref=e260]: GitHub Games + - paragraph [ref=e261]: Server Siege throws you into the midst of a digital fortress under siege by relentless cyber threats. As Mona rallies your defense, you'll coordinate load-balancers and version controls to fortify your network stronghold. Support this game through our crowdfunding platform! + - generic [ref=e262]: View details + - link "Stack Trace Secrets Puzzle Ops Interactive Stack Trace Secrets invites you to decrypt layered error logs and reveal hidden insights within your code. With guidance from Mona, every error message becomes a clue in the puzzle of perfecting your software architecture. Support this game through our crowdfunding platform! View details" [ref=e266] [cursor=pointer]: + - /url: /game/8 + - generic [ref=e269]: + - heading "Stack Trace Secrets" [level=3] [ref=e270] + - generic [ref=e271]: + - generic [ref=e272]: Puzzle + - generic [ref=e273]: Ops Interactive + - paragraph [ref=e274]: Stack Trace Secrets invites you to decrypt layered error logs and reveal hidden insights within your code. With guidance from Mona, every error message becomes a clue in the puzzle of perfecting your software architecture. Support this game through our crowdfunding platform! + - generic [ref=e275]: View details + - link "Syntax Smashdown Action Ops Interactive Syntax Smashdown offers an exhilarating arcade experience where rapid coding reflexes determine the outcome of explosive digital battles. Guided by the fearless Mona, your mission is to knock out glitches and secure the high-score in a realm where syntax is the ultimate weapon. Support this game through our crowdfunding platform! View details" [ref=e279] [cursor=pointer]: + - /url: /game/20 + - generic [ref=e282]: + - heading "Syntax Smashdown" [level=3] [ref=e283] + - generic [ref=e284]: + - generic [ref=e285]: Action + - generic [ref=e286]: Ops Interactive + - paragraph [ref=e287]: Syntax Smashdown offers an exhilarating arcade experience where rapid coding reflexes determine the outcome of explosive digital battles. Guided by the fearless Mona, your mission is to knock out glitches and secure the high-score in a realm where syntax is the ultimate weapon. Support this game through our crowdfunding platform! + - generic [ref=e288]: View details + - link "Terminal Turbulence Action DevMasters Inc. Terminal Turbulence pits you against rapid-fire command line confrontations where timing and precision are of the essence. Let Mona’s digital savvy guide your response strategies as you navigate chaotic server environments in high-octane style. Support this game through our crowdfunding platform! View details" [ref=e292] [cursor=pointer]: + - /url: /game/18 + - generic [ref=e295]: + - heading "Terminal Turbulence" [level=3] [ref=e296] + - generic [ref=e297]: + - generic [ref=e298]: Action + - generic [ref=e299]: DevMasters Inc. + - paragraph [ref=e300]: Terminal Turbulence pits you against rapid-fire command line confrontations where timing and precision are of the essence. Let Mona’s digital savvy guide your response strategies as you navigate chaotic server environments in high-octane style. Support this game through our crowdfunding platform! + - generic [ref=e301]: View details + - link "Virtual Server Simulator Simulation CodeForge Studios Virtual Server Simulator places you in a hyper-realistic data center where resource management is the key to survival. Mona guides you as you balance load distributions and optimize server performance in a dynamic virtual ecosystem. Support this game through our crowdfunding platform! View details" [ref=e305] [cursor=pointer]: + - /url: /game/9 + - generic [ref=e308]: + - heading "Virtual Server Simulator" [level=3] [ref=e309] + - generic [ref=e310]: + - generic [ref=e311]: Simulation + - generic [ref=e312]: CodeForge Studios + - paragraph [ref=e313]: Virtual Server Simulator places you in a hyper-realistic data center where resource management is the key to survival. Mona guides you as you balance load distributions and optimize server performance in a dynamic virtual ecosystem. Support this game through our crowdfunding platform! + - generic [ref=e314]: View details + - generic [ref=e320]: + - button [ref=e321] + - button [ref=e327] + - button [ref=e331] + - button [ref=e336] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-08-26T11-54-34-759Z.yml b/.playwright-mcp/page-2026-08-26T11-54-34-759Z.yml new file mode 100644 index 0000000..e97cff1 --- /dev/null +++ b/.playwright-mcp/page-2026-08-26T11-54-34-759Z.yml @@ -0,0 +1,238 @@ +- generic [ref=e1]: + - banner [ref=e2]: + - generic [ref=e4]: + - button "Toggle menu" [ref=e6] + - link "Tailspin Toys" [ref=e10] [cursor=pointer]: + - /url: / + - main [ref=e11]: + - generic [ref=e13]: + - generic [ref=e14]: + - heading "Welcome to Tailspin Toys" [level=1] [ref=e15] + - paragraph [ref=e16]: Find your next game! And maybe even back one! Explore our collection! + - generic [ref=e17]: + - heading "Filter Games" [level=2] [ref=e18] + - generic [ref=e19]: + - generic [ref=e20]: + - heading "Categories" [level=3] [ref=e21] + - group "Filter by categories" [ref=e22]: + - generic [ref=e23] [cursor=pointer]: + - checkbox "Action" [ref=e24] + - generic [ref=e25]: Action + - generic [ref=e26] [cursor=pointer]: + - checkbox "Adventure" [ref=e27] + - generic [ref=e28]: Adventure + - generic [ref=e29] [cursor=pointer]: + - checkbox "Puzzle" [ref=e30] + - generic [ref=e31]: Puzzle + - generic [ref=e32] [cursor=pointer]: + - checkbox "Simulation" [ref=e33] + - generic [ref=e34]: Simulation + - generic [ref=e35] [cursor=pointer]: + - checkbox "Strategy" [ref=e36] + - generic [ref=e37]: Strategy + - generic [ref=e38]: + - generic [ref=e39]: Publisher + - combobox "Publisher" [active] [ref=e40] [cursor=pointer]: + - option "All Publishers" [selected] + - option "CodeForge Studios" + - option "DevMasters Inc." + - option "GitHub Games" + - option "Ops Interactive" + - button "Reset Filters" [ref=e41] + - generic [ref=e42]: + - heading "Featured Games" [level=2] [ref=e43] + - generic [ref=e44]: + - link "Binary Frontier Adventure DevMasters Inc. Binary Frontier transports you into an uncharted cyber-world where every innovative code unlocks a secret realm. Guided by Mona, explore vast digital landscapes and chart new territories in a narrative steeped in coding mystique. Support this game through our crowdfunding platform! View details" [ref=e45] [cursor=pointer]: + - /url: /game/14 + - generic [ref=e48]: + - heading "Binary Frontier" [level=3] [ref=e49] + - generic [ref=e50]: + - generic [ref=e51]: Adventure + - generic [ref=e52]: DevMasters Inc. + - paragraph [ref=e53]: Binary Frontier transports you into an uncharted cyber-world where every innovative code unlocks a secret realm. Guided by Mona, explore vast digital landscapes and chart new territories in a narrative steeped in coding mystique. Support this game through our crowdfunding platform! + - generic [ref=e54]: View details + - link "Bug Buster Brainteaser Puzzle GitHub Games Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! View details" [ref=e58] [cursor=pointer]: + - /url: /game/7 + - generic [ref=e61]: + - heading "Bug Buster Brainteaser" [level=3] [ref=e62] + - generic [ref=e63]: + - generic [ref=e64]: Puzzle + - generic [ref=e65]: GitHub Games + - paragraph [ref=e66]: Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! + - generic [ref=e67]: View details + - link "Cloud Conqueror Action CodeForge Studios Cloud Conqueror thrusts you into a high-stakes aerial battle against rogue cloud services. With Mona as your co-pilot, navigate through stormy skies and outmaneuver digital adversaries in a quest to reclaim control over your virtual domain. Support this game through our crowdfunding platform! View details" [ref=e71] [cursor=pointer]: + - /url: /game/21 + - generic [ref=e74]: + - heading "Cloud Conqueror" [level=3] [ref=e75] + - generic [ref=e76]: + - generic [ref=e77]: Action + - generic [ref=e78]: CodeForge Studios + - paragraph [ref=e79]: Cloud Conqueror thrusts you into a high-stakes aerial battle against rogue cloud services. With Mona as your co-pilot, navigate through stormy skies and outmaneuver digital adversaries in a quest to reclaim control over your virtual domain. Support this game through our crowdfunding platform! + - generic [ref=e80]: View details + - link "Code Puzzle Chronicles Puzzle CodeForge Studios Code Puzzle Chronicles offers brain-teasing challenges that unravel cryptic algorithms and obscure debugging quests. Mona assists you through each twist, inviting coders to master logic puzzles inspired by real-world coding conundrums. Support this game through our crowdfunding platform! View details" [ref=e84] [cursor=pointer]: + - /url: /game/5 + - generic [ref=e87]: + - heading "Code Puzzle Chronicles" [level=3] [ref=e88] + - generic [ref=e89]: + - generic [ref=e90]: Puzzle + - generic [ref=e91]: CodeForge Studios + - paragraph [ref=e92]: Code Puzzle Chronicles offers brain-teasing challenges that unravel cryptic algorithms and obscure debugging quests. Mona assists you through each twist, inviting coders to master logic puzzles inspired by real-world coding conundrums. Support this game through our crowdfunding platform! + - generic [ref=e93]: View details + - link "Code Quest Odyssey Adventure CodeForge Studios Code Quest Odyssey launches you on an epic journey through enchanted digital realms where coding skills are your passport to discovery. Accompanied by Mona, unravel ancient source codes and conquer challenges that blend narrative with technical ingenuity. Support this game through our crowdfunding platform! View details" [ref=e97] [cursor=pointer]: + - /url: /game/13 + - generic [ref=e100]: + - heading "Code Quest Odyssey" [level=3] [ref=e101] + - generic [ref=e102]: + - generic [ref=e103]: Adventure + - generic [ref=e104]: CodeForge Studios + - paragraph [ref=e105]: Code Quest Odyssey launches you on an epic journey through enchanted digital realms where coding skills are your passport to discovery. Accompanied by Mona, unravel ancient source codes and conquer challenges that blend narrative with technical ingenuity. Support this game through our crowdfunding platform! + - generic [ref=e106]: View details + - link "Container Chaos Simulation DevMasters Inc. Container Chaos replicates the high-stakes environment of container orchestration where every command can either streamline or disrupt your systems. Mona's expert advice will help you navigate the wild world of Docker containers and scalable cloud services. Support this game through our crowdfunding platform! View details" [ref=e110] [cursor=pointer]: + - /url: /game/10 + - generic [ref=e113]: + - heading "Container Chaos" [level=3] [ref=e114] + - generic [ref=e115]: + - generic [ref=e116]: Simulation + - generic [ref=e117]: DevMasters Inc. + - paragraph [ref=e118]: Container Chaos replicates the high-stakes environment of container orchestration where every command can either streamline or disrupt your systems. Mona's expert advice will help you navigate the wild world of Docker containers and scalable cloud services. Support this game through our crowdfunding platform! + - generic [ref=e119]: View details + - link "Deployment Dynasty Simulation Ops Interactive Deployment Dynasty enables you to craft and manage digital empires across complex simulated environments. Mona lends her expertise to help you master scaling, monitoring, and auto-healing routines to maintain your virtual dominion. Support this game through our crowdfunding platform! View details" [ref=e123] [cursor=pointer]: + - /url: /game/12 + - generic [ref=e126]: + - heading "Deployment Dynasty" [level=3] [ref=e127] + - generic [ref=e128]: + - generic [ref=e129]: Simulation + - generic [ref=e130]: Ops Interactive + - paragraph [ref=e131]: Deployment Dynasty enables you to craft and manage digital empires across complex simulated environments. Mona lends her expertise to help you master scaling, monitoring, and auto-healing routines to maintain your virtual dominion. Support this game through our crowdfunding platform! + - generic [ref=e132]: View details + - link "DevOps Dominion Strategy CodeForge Studios In DevOps Dominion, strategic planning meets advanced deployment tactics in a fast-paced battlefield of code. Mona leads your team of digital warriors through orchestrated pipelines and microservice skirmishes, ensuring every command brings a competitive edge. Support this game through our crowdfunding platform! View details" [ref=e136] [cursor=pointer]: + - /url: /game/1 + - generic [ref=e139]: + - heading "DevOps Dominion" [level=3] [ref=e140] + - generic [ref=e141]: + - generic [ref=e142]: Strategy + - generic [ref=e143]: CodeForge Studios + - paragraph [ref=e144]: In DevOps Dominion, strategic planning meets advanced deployment tactics in a fast-paced battlefield of code. Mona leads your team of digital warriors through orchestrated pipelines and microservice skirmishes, ensuring every command brings a competitive edge. Support this game through our crowdfunding platform! + - generic [ref=e145]: View details + - link "Digital Debugger's Dream Adventure GitHub Games Digital Debugger's Dream pioneers an immersive adventure that merges investigative quests with real-life debugging scenarios. As Mona champions your journey, each step deepens the mystery behind a cybernetic riddle waiting to be resolved. Support this game through our crowdfunding platform! View details" [ref=e149] [cursor=pointer]: + - /url: /game/15 + - generic [ref=e152]: + - heading "Digital Debugger's Dream" [level=3] [ref=e153] + - generic [ref=e154]: + - generic [ref=e155]: Adventure + - generic [ref=e156]: GitHub Games + - paragraph [ref=e157]: Digital Debugger's Dream pioneers an immersive adventure that merges investigative quests with real-life debugging scenarios. As Mona champions your journey, each step deepens the mystery behind a cybernetic riddle waiting to be resolved. Support this game through our crowdfunding platform! + - generic [ref=e158]: View details + - link "Infrastructure Innovator Simulation GitHub Games Infrastructure Innovator simulates a sprawling digital ecosystem that challenges you to build robust networks from scratch. With Mona’s strategic tips, you’ll design and implement systems that stand up to relentless virtual stress tests. Support this game through our crowdfunding platform! View details" [ref=e162] [cursor=pointer]: + - /url: /game/11 + - generic [ref=e165]: + - heading "Infrastructure Innovator" [level=3] [ref=e166] + - generic [ref=e167]: + - generic [ref=e168]: Simulation + - generic [ref=e169]: GitHub Games + - paragraph [ref=e170]: Infrastructure Innovator simulates a sprawling digital ecosystem that challenges you to build robust networks from scratch. With Mona’s strategic tips, you’ll design and implement systems that stand up to relentless virtual stress tests. Support this game through our crowdfunding platform! + - generic [ref=e171]: View details + - link "Merge Conflict Mystery Puzzle DevMasters Inc. Merge Conflict Mystery immerses you in a labyrinth of code merges where every puzzle piece is a potential breakthrough. With Mona helping decode errors, your task is to resolve conflicts and streamline integration across complex code branches. Support this game through our crowdfunding platform! View details" [ref=e175] [cursor=pointer]: + - /url: /game/6 + - generic [ref=e178]: + - heading "Merge Conflict Mystery" [level=3] [ref=e179] + - generic [ref=e180]: + - generic [ref=e181]: Puzzle + - generic [ref=e182]: DevMasters Inc. + - paragraph [ref=e183]: Merge Conflict Mystery immerses you in a labyrinth of code merges where every puzzle piece is a potential breakthrough. With Mona helping decode errors, your task is to resolve conflicts and streamline integration across complex code branches. Support this game through our crowdfunding platform! + - generic [ref=e184]: View details + - link "Pipeline Conquest Strategy DevMasters Inc. Pipeline Conquest challenges players to optimize continuous integration workflows while countering unforeseen system failures. With Mona by your side, organize automated builds and deployment pipelines in real time to secure lasting digital victory. Support this game through our crowdfunding platform! View details" [ref=e188] [cursor=pointer]: + - /url: /game/2 + - generic [ref=e191]: + - heading "Pipeline Conquest" [level=3] [ref=e192] + - generic [ref=e193]: + - generic [ref=e194]: Strategy + - generic [ref=e195]: DevMasters Inc. + - paragraph [ref=e196]: Pipeline Conquest challenges players to optimize continuous integration workflows while countering unforeseen system failures. With Mona by your side, organize automated builds and deployment pipelines in real time to secure lasting digital victory. Support this game through our crowdfunding platform! + - generic [ref=e197]: View details + - link "Refactor Realms Adventure Ops Interactive Refactor Realms beckons you into a world where systematic code improvement reshapes ancient digital civilizations. With Mona’s mentorship, transform legacy systems into streamlined masterpieces as you explore breathtaking virtual environments. Support this game through our crowdfunding platform! View details" [ref=e201] [cursor=pointer]: + - /url: /game/16 + - generic [ref=e204]: + - heading "Refactor Realms" [level=3] [ref=e205] + - generic [ref=e206]: + - generic [ref=e207]: Adventure + - generic [ref=e208]: Ops Interactive + - paragraph [ref=e209]: Refactor Realms beckons you into a world where systematic code improvement reshapes ancient digital civilizations. With Mona’s mentorship, transform legacy systems into streamlined masterpieces as you explore breathtaking virtual environments. Support this game through our crowdfunding platform! + - generic [ref=e210]: View details + - link "Repo Rampart Action GitHub Games Repo Rampart immerses you in adrenaline-charged defense missions where every command must protect your precious codebases. With Mona leading your strategy, prevent intrusions and execute swift countermeasures in electrifying action sequences. Support this game through our crowdfunding platform! View details" [ref=e214] [cursor=pointer]: + - /url: /game/19 + - generic [ref=e217]: + - heading "Repo Rampart" [level=3] [ref=e218] + - generic [ref=e219]: + - generic [ref=e220]: Action + - generic [ref=e221]: GitHub Games + - paragraph [ref=e222]: Repo Rampart immerses you in adrenaline-charged defense missions where every command must protect your precious codebases. With Mona leading your strategy, prevent intrusions and execute swift countermeasures in electrifying action sequences. Support this game through our crowdfunding platform! + - generic [ref=e223]: View details + - link "Repo Rulers Strategy Ops Interactive Repo Rulers demands razor-sharp tactics and agile repository management to dominate interconnected servers. Under Mona’s guidance, you'll enforce branch protections and manage pull requests in a high-stakes arena where precision is paramount. Support this game through our crowdfunding platform! View details" [ref=e227] [cursor=pointer]: + - /url: /game/4 + - generic [ref=e230]: + - heading "Repo Rulers" [level=3] [ref=e231] + - generic [ref=e232]: + - generic [ref=e233]: Strategy + - generic [ref=e234]: Ops Interactive + - paragraph [ref=e235]: Repo Rulers demands razor-sharp tactics and agile repository management to dominate interconnected servers. Under Mona’s guidance, you'll enforce branch protections and manage pull requests in a high-stakes arena where precision is paramount. Support this game through our crowdfunding platform! + - generic [ref=e236]: View details + - link "Script Strike Action CodeForge Studios Script Strike propels you into a fast-paced coding battleground where every keystroke could change the tide of an intense conflict. Mona rallies your forces as you dive into real-time challenges that merge reflexes with smart script execution. Support this game through our crowdfunding platform! View details" [ref=e240] [cursor=pointer]: + - /url: /game/17 + - generic [ref=e243]: + - heading "Script Strike" [level=3] [ref=e244] + - generic [ref=e245]: + - generic [ref=e246]: Action + - generic [ref=e247]: CodeForge Studios + - paragraph [ref=e248]: Script Strike propels you into a fast-paced coding battleground where every keystroke could change the tide of an intense conflict. Mona rallies your forces as you dive into real-time challenges that merge reflexes with smart script execution. Support this game through our crowdfunding platform! + - generic [ref=e249]: View details + - link "Server Siege Strategy GitHub Games Server Siege throws you into the midst of a digital fortress under siege by relentless cyber threats. As Mona rallies your defense, you'll coordinate load-balancers and version controls to fortify your network stronghold. Support this game through our crowdfunding platform! View details" [ref=e253] [cursor=pointer]: + - /url: /game/3 + - generic [ref=e256]: + - heading "Server Siege" [level=3] [ref=e257] + - generic [ref=e258]: + - generic [ref=e259]: Strategy + - generic [ref=e260]: GitHub Games + - paragraph [ref=e261]: Server Siege throws you into the midst of a digital fortress under siege by relentless cyber threats. As Mona rallies your defense, you'll coordinate load-balancers and version controls to fortify your network stronghold. Support this game through our crowdfunding platform! + - generic [ref=e262]: View details + - link "Stack Trace Secrets Puzzle Ops Interactive Stack Trace Secrets invites you to decrypt layered error logs and reveal hidden insights within your code. With guidance from Mona, every error message becomes a clue in the puzzle of perfecting your software architecture. Support this game through our crowdfunding platform! View details" [ref=e266] [cursor=pointer]: + - /url: /game/8 + - generic [ref=e269]: + - heading "Stack Trace Secrets" [level=3] [ref=e270] + - generic [ref=e271]: + - generic [ref=e272]: Puzzle + - generic [ref=e273]: Ops Interactive + - paragraph [ref=e274]: Stack Trace Secrets invites you to decrypt layered error logs and reveal hidden insights within your code. With guidance from Mona, every error message becomes a clue in the puzzle of perfecting your software architecture. Support this game through our crowdfunding platform! + - generic [ref=e275]: View details + - link "Syntax Smashdown Action Ops Interactive Syntax Smashdown offers an exhilarating arcade experience where rapid coding reflexes determine the outcome of explosive digital battles. Guided by the fearless Mona, your mission is to knock out glitches and secure the high-score in a realm where syntax is the ultimate weapon. Support this game through our crowdfunding platform! View details" [ref=e279] [cursor=pointer]: + - /url: /game/20 + - generic [ref=e282]: + - heading "Syntax Smashdown" [level=3] [ref=e283] + - generic [ref=e284]: + - generic [ref=e285]: Action + - generic [ref=e286]: Ops Interactive + - paragraph [ref=e287]: Syntax Smashdown offers an exhilarating arcade experience where rapid coding reflexes determine the outcome of explosive digital battles. Guided by the fearless Mona, your mission is to knock out glitches and secure the high-score in a realm where syntax is the ultimate weapon. Support this game through our crowdfunding platform! + - generic [ref=e288]: View details + - link "Terminal Turbulence Action DevMasters Inc. Terminal Turbulence pits you against rapid-fire command line confrontations where timing and precision are of the essence. Let Mona’s digital savvy guide your response strategies as you navigate chaotic server environments in high-octane style. Support this game through our crowdfunding platform! View details" [ref=e292] [cursor=pointer]: + - /url: /game/18 + - generic [ref=e295]: + - heading "Terminal Turbulence" [level=3] [ref=e296] + - generic [ref=e297]: + - generic [ref=e298]: Action + - generic [ref=e299]: DevMasters Inc. + - paragraph [ref=e300]: Terminal Turbulence pits you against rapid-fire command line confrontations where timing and precision are of the essence. Let Mona’s digital savvy guide your response strategies as you navigate chaotic server environments in high-octane style. Support this game through our crowdfunding platform! + - generic [ref=e301]: View details + - link "Virtual Server Simulator Simulation CodeForge Studios Virtual Server Simulator places you in a hyper-realistic data center where resource management is the key to survival. Mona guides you as you balance load distributions and optimize server performance in a dynamic virtual ecosystem. Support this game through our crowdfunding platform! View details" [ref=e305] [cursor=pointer]: + - /url: /game/9 + - generic [ref=e308]: + - heading "Virtual Server Simulator" [level=3] [ref=e309] + - generic [ref=e310]: + - generic [ref=e311]: Simulation + - generic [ref=e312]: CodeForge Studios + - paragraph [ref=e313]: Virtual Server Simulator places you in a hyper-realistic data center where resource management is the key to survival. Mona guides you as you balance load distributions and optimize server performance in a dynamic virtual ecosystem. Support this game through our crowdfunding platform! + - generic [ref=e314]: View details + - generic [ref=e320]: + - button [ref=e321] + - button [ref=e327] + - button [ref=e331] + - button [ref=e336] \ No newline at end of file diff --git a/.playwright-mcp/page-2026-08-26T11-55-04-845Z.yml b/.playwright-mcp/page-2026-08-26T11-55-04-845Z.yml new file mode 100644 index 0000000..b00febd --- /dev/null +++ b/.playwright-mcp/page-2026-08-26T11-55-04-845Z.yml @@ -0,0 +1,57 @@ +- generic [ref=e1]: + - banner [ref=e2]: + - generic [ref=e4]: + - button "Toggle menu" [ref=e6] + - link "Tailspin Toys" [ref=e10] [cursor=pointer]: + - /url: / + - main [ref=e11]: + - generic [ref=e13]: + - generic [ref=e14]: + - heading "Welcome to Tailspin Toys" [level=1] [ref=e15] + - paragraph [ref=e16]: Find your next game! And maybe even back one! Explore our collection! + - generic [ref=e17]: + - heading "Filter Games" [level=2] [ref=e18] + - generic [ref=e19]: + - generic [ref=e20]: + - heading "Categories" [level=3] [ref=e21] + - group "Filter by categories" [ref=e22]: + - generic [ref=e23] [cursor=pointer]: + - checkbox "Action" [ref=e24] + - generic [ref=e25]: Action + - generic [ref=e26] [cursor=pointer]: + - checkbox "Adventure" [ref=e27] + - generic [ref=e28]: Adventure + - generic [ref=e29] [cursor=pointer]: + - checkbox "Puzzle" [checked] [active] [ref=e30] + - generic [ref=e31]: Puzzle + - generic [ref=e32] [cursor=pointer]: + - checkbox "Simulation" [ref=e33] + - generic [ref=e34]: Simulation + - generic [ref=e35] [cursor=pointer]: + - checkbox "Strategy" [ref=e36] + - generic [ref=e37]: Strategy + - generic [ref=e38]: + - generic [ref=e39]: Publisher + - combobox "Publisher" [ref=e40] [cursor=pointer]: + - option "All Publishers" + - option "CodeForge Studios" + - option "DevMasters Inc." + - option "GitHub Games" [selected] + - option "Ops Interactive" + - button "Reset Filters" [ref=e41] + - generic [ref=e42]: + - heading "Featured Games" [level=2] [ref=e43] + - link "Bug Buster Brainteaser Puzzle GitHub Games Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! View details" [ref=e58] [cursor=pointer]: + - /url: /game/7 + - generic [ref=e61]: + - heading "Bug Buster Brainteaser" [level=3] [ref=e62] + - generic [ref=e63]: + - generic [ref=e64]: Puzzle + - generic [ref=e65]: GitHub Games + - paragraph [ref=e66]: Bug Buster Brainteaser tests your analytical skills with clever puzzles that simulate real-world debugging adventures. Mona empowers you to track down elusive bugs, transforming each challenge into a rewarding quest for clarity and efficiency. Support this game through our crowdfunding platform! + - generic [ref=e67]: View details + - generic [ref=e320]: + - button [ref=e321] + - button [ref=e327] + - button [ref=e331] + - button [ref=e336] \ No newline at end of file diff --git a/combined-filters-result.png b/combined-filters-result.png new file mode 100644 index 0000000..b3e251d Binary files /dev/null and b/combined-filters-result.png differ diff --git a/e2e-tests/accessibility.spec.ts b/e2e-tests/accessibility.spec.ts index 954fa9f..665ba22 100644 --- a/e2e-tests/accessibility.spec.ts +++ b/e2e-tests/accessibility.spec.ts @@ -88,7 +88,7 @@ test.describe('Accessibility Tests', () => { await page.keyboard.press('Tab'); tabCount++; } - return page.locator('[data-testid="game-card"]:focus').count(); + return page.locator('[data-testid^="game-card-"]:focus').count(); }, { timeout: 15000, message: 'Expected a game card to receive focus via Tab' }).toBeGreaterThan(0); }); }); @@ -110,7 +110,7 @@ test.describe('Accessibility Tests', () => { const focusedElement = page.locator(':focus'); const testId = await focusedElement.getAttribute('data-testid').catch(() => null); - if (testId === 'game-card') { + if (testId && testId.startsWith('game-card-')) { gameId = await focusedElement.getAttribute('data-game-id'); gameCardFocused = true; } @@ -210,7 +210,7 @@ test.describe('Accessibility Tests', () => { await expect(menuButtonSvg).toHaveAttribute('aria-hidden', 'true'); // Check game card arrow SVGs have aria-hidden (scope to first card to avoid strict mode violation) - const firstGameCard = page.locator('[data-testid="game-card"]').first(); + const firstGameCard = page.locator('[data-testid^="game-card-"]').first(); const gameCardSvgs = firstGameCard.locator('svg'); const count = await gameCardSvgs.count(); diff --git a/e2e-tests/filtering.spec.ts b/e2e-tests/filtering.spec.ts new file mode 100644 index 0000000..6536bf6 --- /dev/null +++ b/e2e-tests/filtering.spec.ts @@ -0,0 +1,215 @@ +import { test, expect } from '@playwright/test'; + +test.describe('Game Filtering', () => { + test.beforeEach(async ({ page }) => { + await page.goto('/'); + }); + + test('should display filter controls', async ({ page }) => { + await test.step('Verify filter controls are visible', async () => { + const filterControls = page.getByTestId('filter-controls'); + await expect(filterControls).toBeVisible(); + await expect(page.getByRole('group', { name: 'Filter by categories' })).toBeVisible(); + await expect(page.getByLabel('Publisher')).toBeVisible(); + await expect(page.getByTestId('reset-filters')).toBeVisible(); + }); + }); + + test('should filter games by single category', async ({ page }) => { + await test.step('Count initial games', async () => { + const gameCards = page.locator('[data-testid^="game-card-"]'); + const initialCount = await gameCards.count(); + expect(initialCount).toBeGreaterThan(0); + }); + + await test.step('Select a category filter', async () => { + // Get the first category checkbox + const firstCategoryCheckbox = page.locator('input[name="category"]').first(); + await firstCategoryCheckbox.check(); + }); + + await test.step('Verify filtered results', async () => { + const gameCards = page.locator('[data-testid^="game-card-"]').filter({ hasNotText: '' }); + const visibleCards = await gameCards.evaluateAll((cards) => + cards.filter((card) => (card as HTMLElement).style.display !== 'none') + ); + + // At least one game should be visible (we have test data) + expect(visibleCards.length).toBeGreaterThan(0); + }); + }); + + test('should filter games by multiple categories', async ({ page }) => { + await test.step('Select multiple categories', async () => { + const categoryCheckboxes = page.locator('input[name="category"]'); + const checkboxCount = await categoryCheckboxes.count(); + + if (checkboxCount >= 2) { + await categoryCheckboxes.nth(0).check(); + await categoryCheckboxes.nth(1).check(); + } + }); + + await test.step('Verify multiple category filtering', async () => { + const gameCards = page.locator('[data-testid^="game-card-"]'); + + // Check that visible cards match one of the selected categories + const visibleCards = await gameCards.evaluateAll((cards) => + cards.filter((card) => (card as HTMLElement).style.display !== 'none') + ); + + expect(visibleCards.length).toBeGreaterThan(0); + }); + }); + + test('should filter games by publisher', async ({ page }) => { + await test.step('Select a publisher', async () => { + const publisherSelect = page.getByTestId('filter-publisher'); + await expect(publisherSelect).toBeVisible(); + + // Select the first non-empty option + await publisherSelect.selectOption({ index: 1 }); + }); + + await test.step('Verify publisher filtering', async () => { + const gameCards = page.locator('[data-testid^="game-card-"]'); + const visibleCards = await gameCards.evaluateAll((cards) => + cards.filter((card) => (card as HTMLElement).style.display !== 'none') + ); + + expect(visibleCards.length).toBeGreaterThan(0); + }); + }); + + test('should combine category and publisher filters', async ({ page }) => { + await test.step('Select both category and publisher filters', async () => { + // Select a category + const firstCategoryCheckbox = page.locator('input[name="category"]').first(); + await firstCategoryCheckbox.check(); + + // Select a publisher + const publisherSelect = page.getByTestId('filter-publisher'); + await publisherSelect.selectOption({ index: 1 }); + }); + + await test.step('Verify combined filtering', async () => { + const gameCards = page.locator('[data-testid^="game-card-"]'); + + // Some games should still be visible (or none if no match) + const visibleCards = await gameCards.evaluateAll((cards) => + cards.filter((card) => (card as HTMLElement).style.display !== 'none') + ); + + // The filtering should have narrowed down results (or shown no matches message) + expect(visibleCards.length).toBeGreaterThanOrEqual(0); + }); + }); + + test('should reset filters when reset button is clicked', async ({ page }) => { + let initialCount: number; + + await test.step('Count initial games', async () => { + const gameCards = page.locator('[data-testid^="game-card-"]'); + initialCount = await gameCards.count(); + }); + + await test.step('Apply filters', async () => { + const firstCategoryCheckbox = page.locator('input[name="category"]').first(); + await firstCategoryCheckbox.check(); + + const publisherSelect = page.getByTestId('filter-publisher'); + await publisherSelect.selectOption({ index: 1 }); + }); + + await test.step('Reset filters', async () => { + await page.getByTestId('reset-filters').click(); + }); + + await test.step('Verify all games are visible again', async () => { + const gameCards = page.locator('[data-testid^="game-card-"]'); + const visibleCards = await gameCards.evaluateAll((cards) => + cards.filter((card) => (card as HTMLElement).style.display !== 'none') + ); + + expect(visibleCards.length).toBe(initialCount); + }); + + await test.step('Verify filters are cleared', async () => { + // Check that no category checkboxes are checked + const checkedCategories = await page.locator('input[name="category"]:checked').count(); + expect(checkedCategories).toBe(0); + + // Check that publisher select is reset + const publisherSelect = page.getByTestId('filter-publisher'); + await expect(publisherSelect).toHaveValue(''); + }); + }); + + test('should show empty state when no games match filters', async ({ page }) => { + await test.step('Select filters that likely have no matches', async () => { + // Select all categories to maximize chance of finding an impossible combination + const categoryCheckboxes = page.locator('input[name="category"]'); + const count = await categoryCheckboxes.count(); + + // Check first category + if (count > 0) { + await categoryCheckboxes.first().check(); + } + + // Try selecting a publisher that doesn't have games in that category + // This might show the empty state depending on the data + const publisherSelect = page.getByTestId('filter-publisher'); + const optionCount = await publisherSelect.locator('option').count(); + + if (optionCount > 2) { + await publisherSelect.selectOption({ index: optionCount - 1 }); + } + }); + + await test.step('Check for empty state or visible games', async () => { + // Either we see games or the empty state message + const emptyState = page.getByTestId('filtered-empty-state'); + const gameCards = page.locator('[data-testid^="game-card-"]'); + const visibleCards = await gameCards.evaluateAll((cards) => + cards.filter((card) => (card as HTMLElement).style.display !== 'none') + ); + + if (visibleCards.length === 0) { + await expect(emptyState).toBeVisible(); + await expect(emptyState).toContainText('No games match the selected filters'); + } else { + await expect(emptyState).not.toBeVisible(); + } + }); + }); + + test('should support keyboard navigation', async ({ page }) => { + await test.step('Tab to category checkboxes', async () => { + const firstCheckbox = page.locator('input[name="category"]').first(); + await firstCheckbox.focus(); + await expect(firstCheckbox).toBeFocused(); + }); + + await test.step('Tab to publisher select', async () => { + const publisherSelect = page.getByTestId('filter-publisher'); + await publisherSelect.focus(); + await expect(publisherSelect).toBeFocused(); + }); + + await test.step('Tab to reset button', async () => { + const resetButton = page.getByTestId('reset-filters'); + await resetButton.focus(); + await expect(resetButton).toBeFocused(); + }); + + await test.step('Activate reset button with keyboard', async () => { + const resetButton = page.getByTestId('reset-filters'); + await resetButton.focus(); + await resetButton.press('Enter'); + + // Verify filters were reset + const checkedCategories = await page.locator('input[name="category"]:checked').count(); + expect(checkedCategories).toBe(0); + }); + }); +}); diff --git a/e2e-tests/games.spec.ts b/e2e-tests/games.spec.ts index d447f1e..297633c 100644 --- a/e2e-tests/games.spec.ts +++ b/e2e-tests/games.spec.ts @@ -12,13 +12,13 @@ test.describe('Game Listing and Navigation', () => { }); await test.step('Verify game cards are displayed', async () => { - const gameCards = page.getByTestId('game-card'); + const gameCards = page.locator('[data-testid^="game-card-"]'); await expect(gameCards.first()).toBeVisible(); expect(await gameCards.count()).toBeGreaterThan(0); }); await test.step('Verify game cards have titles with content', async () => { - const gameCards = page.getByTestId('game-card'); + const gameCards = page.locator('[data-testid^="game-card-"]'); await expect(gameCards.first().getByTestId('game-title')).toBeVisible(); await expect(gameCards.first().getByTestId('game-title')).not.toBeEmpty(); }); @@ -35,7 +35,7 @@ test.describe('Game Listing and Navigation', () => { }); await test.step('Get first game information and click it', async () => { - const firstGameCard = page.getByTestId('game-card').first(); + const firstGameCard = page.locator('[data-testid^="game-card-"]').first(); gameId = await firstGameCard.getAttribute('data-game-id'); gameTitle = await firstGameCard.getAttribute('data-game-title'); await firstGameCard.click(); diff --git a/src/components/FilterControls.astro b/src/components/FilterControls.astro new file mode 100644 index 0000000..6778a79 --- /dev/null +++ b/src/components/FilterControls.astro @@ -0,0 +1,182 @@ +--- +/** + * FilterControls component + * Provides client-side filtering controls for games by category and publisher. + */ +import type { Category, Publisher } from '../types/game'; + +interface Props { + categories: Category[]; + publishers: Publisher[]; +} + +const { categories, publishers } = Astro.props; +--- + +
+

Filter Games

+ +
+ +
+

Categories

+
+ {categories.map((category) => ( + + ))} +
+
+ + +
+ + +
+ + + +
+
+ + diff --git a/src/components/GameCard.astro b/src/components/GameCard.astro index da71b54..2aa450b 100644 --- a/src/components/GameCard.astro +++ b/src/components/GameCard.astro @@ -13,9 +13,11 @@ const { game } = Astro.props;
diff --git a/src/lib/categories.test.ts b/src/lib/categories.test.ts new file mode 100644 index 0000000..c2bfcfa --- /dev/null +++ b/src/lib/categories.test.ts @@ -0,0 +1,41 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { createTestDatabase } from '../../db/test-helpers'; +import { categories } from '../../db/schema'; +import type { Database } from './db'; +import { getAllCategories } from './categories'; + +describe('categories data-access helpers', () => { + let db: Database; + + beforeEach(async () => { + db = await createTestDatabase(); + }); + + it('returns all categories ordered by name', async () => { + // Insert in reverse alphabetical order to test ordering + await db.insert(categories).values({ name: 'Strategy', description: 'Strategic games' }); + await db.insert(categories).values({ name: 'Action', description: 'Action games' }); + await db.insert(categories).values({ name: 'Puzzle', description: 'Puzzle games' }); + + const all = await getAllCategories(db); + + expect(all).toHaveLength(3); + expect(all.map((c) => c.name)).toEqual(['Action', 'Puzzle', 'Strategy']); + expect(all[0]).toEqual({ id: expect.any(Number), name: 'Action' }); + }); + + it('returns empty array when no categories exist', async () => { + const all = await getAllCategories(db); + expect(all).toEqual([]); + }); + + it('returns only id and name fields', async () => { + await db.insert(categories).values({ name: 'RPG', description: 'Role-playing games' }); + + const all = await getAllCategories(db); + + expect(all).toHaveLength(1); + expect(all[0]).toEqual({ id: expect.any(Number), name: 'RPG' }); + expect(all[0]).not.toHaveProperty('description'); + }); +}); diff --git a/src/lib/categories.ts b/src/lib/categories.ts new file mode 100644 index 0000000..7f26efc --- /dev/null +++ b/src/lib/categories.ts @@ -0,0 +1,31 @@ +/** + * Data-access helpers for category summary records used by Astro pages. + */ + +import { asc } from 'drizzle-orm'; +import type { Database } from './db'; +import { categories } from '../../db/schema'; +import type { Category } from '../types/game'; + +type CategorySummaryRow = { + id: number; + name: string; +}; + +/** + * Returns all categories ordered by name. + * + * @param db - Drizzle database client. + * @returns A list of category summaries including only `id` and `name`. + */ +export async function getAllCategories(db: Database): Promise { + const rows = await db + .select({ id: categories.id, name: categories.name }) + .from(categories) + .orderBy(asc(categories.name)); + + return rows.map((row: CategorySummaryRow) => ({ + id: row.id, + name: row.name, + })); +} diff --git a/src/lib/games.test.ts b/src/lib/games.test.ts index efea6b6..12c25e7 100644 --- a/src/lib/games.test.ts +++ b/src/lib/games.test.ts @@ -6,6 +6,7 @@ import { getAllGames, getAllGameIds, getGameById, + type GameFilters, } from './games'; async function seedGames(db: Database, count: number): Promise { @@ -63,4 +64,199 @@ describe('games data-access helpers', () => { await seedGames(db, 2); expect(await getGameById(db, 99999)).toBeNull(); }); + + describe('filtering', () => { + it('filters games by single category', async () => { + const [cat1] = await db + .insert(categories) + .values({ name: 'Strategy' }) + .returning({ id: categories.id }); + const [cat2] = await db + .insert(categories) + .values({ name: 'Action' }) + .returning({ id: categories.id }); + const [pub] = await db + .insert(publishers) + .values({ name: 'Publisher' }) + .returning({ id: publishers.id }); + + await db.insert(games).values({ + title: 'Strategy Game', + description: 'A strategy game', + categoryId: cat1.id, + publisherId: pub.id, + }); + await db.insert(games).values({ + title: 'Action Game', + description: 'An action game', + categoryId: cat2.id, + publisherId: pub.id, + }); + + const filters: GameFilters = { categoryIds: [cat1.id] }; + const filtered = await getAllGames(db, filters); + + expect(filtered).toHaveLength(1); + expect(filtered[0].title).toBe('Strategy Game'); + }); + + it('filters games by multiple categories', async () => { + const [cat1] = await db + .insert(categories) + .values({ name: 'Strategy' }) + .returning({ id: categories.id }); + const [cat2] = await db + .insert(categories) + .values({ name: 'Action' }) + .returning({ id: categories.id }); + const [cat3] = await db + .insert(categories) + .values({ name: 'Puzzle' }) + .returning({ id: categories.id }); + const [pub] = await db + .insert(publishers) + .values({ name: 'Publisher' }) + .returning({ id: publishers.id }); + + await db.insert(games).values({ + title: 'Strategy Game', + description: 'A strategy game', + categoryId: cat1.id, + publisherId: pub.id, + }); + await db.insert(games).values({ + title: 'Action Game', + description: 'An action game', + categoryId: cat2.id, + publisherId: pub.id, + }); + await db.insert(games).values({ + title: 'Puzzle Game', + description: 'A puzzle game', + categoryId: cat3.id, + publisherId: pub.id, + }); + + const filters: GameFilters = { categoryIds: [cat1.id, cat3.id] }; + const filtered = await getAllGames(db, filters); + + expect(filtered).toHaveLength(2); + expect(filtered.map((g) => g.title).sort()).toEqual(['Puzzle Game', 'Strategy Game']); + }); + + it('filters games by publisher', async () => { + const [cat] = await db + .insert(categories) + .values({ name: 'Strategy' }) + .returning({ id: categories.id }); + const [pub1] = await db + .insert(publishers) + .values({ name: 'Publisher One' }) + .returning({ id: publishers.id }); + const [pub2] = await db + .insert(publishers) + .values({ name: 'Publisher Two' }) + .returning({ id: publishers.id }); + + await db.insert(games).values({ + title: 'Game from Pub1', + description: 'A game', + categoryId: cat.id, + publisherId: pub1.id, + }); + await db.insert(games).values({ + title: 'Another Game from Pub1', + description: 'Another game', + categoryId: cat.id, + publisherId: pub1.id, + }); + await db.insert(games).values({ + title: 'Game from Pub2', + description: 'A game', + categoryId: cat.id, + publisherId: pub2.id, + }); + + const filters: GameFilters = { publisherId: pub1.id }; + const filtered = await getAllGames(db, filters); + + expect(filtered).toHaveLength(2); + expect(filtered.every((g) => g.publisher?.id === pub1.id)).toBe(true); + }); + + it('filters games by both category and publisher', async () => { + const [cat1] = await db + .insert(categories) + .values({ name: 'Strategy' }) + .returning({ id: categories.id }); + const [cat2] = await db + .insert(categories) + .values({ name: 'Action' }) + .returning({ id: categories.id }); + const [pub1] = await db + .insert(publishers) + .values({ name: 'Publisher One' }) + .returning({ id: publishers.id }); + const [pub2] = await db + .insert(publishers) + .values({ name: 'Publisher Two' }) + .returning({ id: publishers.id }); + + await db.insert(games).values({ + title: 'Strategy from Pub1', + description: 'A game', + categoryId: cat1.id, + publisherId: pub1.id, + }); + await db.insert(games).values({ + title: 'Action from Pub1', + description: 'A game', + categoryId: cat2.id, + publisherId: pub1.id, + }); + await db.insert(games).values({ + title: 'Strategy from Pub2', + description: 'A game', + categoryId: cat1.id, + publisherId: pub2.id, + }); + + const filters: GameFilters = { categoryIds: [cat1.id], publisherId: pub1.id }; + const filtered = await getAllGames(db, filters); + + expect(filtered).toHaveLength(1); + expect(filtered[0].title).toBe('Strategy from Pub1'); + }); + + it('returns all games when no filters are provided', async () => { + await seedGames(db, 3); + const all = await getAllGames(db); + const filtered = await getAllGames(db, {}); + + expect(filtered).toEqual(all); + }); + + it('returns empty array when filters match no games', async () => { + const [cat] = await db + .insert(categories) + .values({ name: 'Strategy' }) + .returning({ id: categories.id }); + const [pub] = await db + .insert(publishers) + .values({ name: 'Publisher' }) + .returning({ id: publishers.id }); + + await db.insert(games).values({ + title: 'Game', + description: 'A game', + categoryId: cat.id, + publisherId: pub.id, + }); + + const filters: GameFilters = { categoryIds: [99999] }; + const filtered = await getAllGames(db, filters); + + expect(filtered).toEqual([]); + }); + }); }); diff --git a/src/lib/games.ts b/src/lib/games.ts index 4ed218e..0225961 100644 --- a/src/lib/games.ts +++ b/src/lib/games.ts @@ -1,8 +1,13 @@ -import { eq, asc } from 'drizzle-orm'; +import { eq, asc, and, inArray } from 'drizzle-orm'; import type { Database } from './db'; import { games, categories, publishers } from '../../db/schema'; import type { Game } from '../types/game'; +export interface GameFilters { + categoryIds?: number[]; + publisherId?: number; +} + const gameSelection = { id: games.id, title: games.title, @@ -50,10 +55,26 @@ function baseGamesQuery(db: Database) { .leftJoin(publishers, eq(games.publisherId, publishers.id)); } -/** All games ordered by title. */ -export async function getAllGames(db: Database): Promise { - const rows = await baseGamesQuery(db).orderBy(asc(games.title)); - return rows.map(mapGame); +/** All games ordered by title. Optionally filter by category IDs and/or publisher ID. */ +export async function getAllGames(db: Database, filters?: GameFilters): Promise { + // Build filter conditions + const conditions = []; + if (filters?.categoryIds && filters.categoryIds.length > 0) { + conditions.push(inArray(games.categoryId, filters.categoryIds)); + } + if (filters?.publisherId !== undefined) { + conditions.push(eq(games.publisherId, filters.publisherId)); + } + + // Build and execute query + const query = baseGamesQuery(db); + if (conditions.length > 0) { + const rows = await query.where(and(...conditions)).orderBy(asc(games.title)); + return rows.map(mapGame); + } else { + const rows = await query.orderBy(asc(games.title)); + return rows.map(mapGame); + } } /** All game ids ordered by title. */ diff --git a/src/lib/publishers.test.ts b/src/lib/publishers.test.ts new file mode 100644 index 0000000..30bf816 --- /dev/null +++ b/src/lib/publishers.test.ts @@ -0,0 +1,41 @@ +import { describe, it, expect, beforeEach } from 'vitest'; +import { createTestDatabase } from '../../db/test-helpers'; +import { publishers } from '../../db/schema'; +import type { Database } from './db'; +import { getAllPublishers } from './publishers'; + +describe('publishers data-access helpers', () => { + let db: Database; + + beforeEach(async () => { + db = await createTestDatabase(); + }); + + it('returns all publishers ordered by name', async () => { + // Insert in reverse alphabetical order to test ordering + await db.insert(publishers).values({ name: 'Zeta Games', description: 'A publisher' }); + await db.insert(publishers).values({ name: 'Alpha Studios', description: 'A publisher' }); + await db.insert(publishers).values({ name: 'Mega Corp', description: 'A publisher' }); + + const all = await getAllPublishers(db); + + expect(all).toHaveLength(3); + expect(all.map((p) => p.name)).toEqual(['Alpha Studios', 'Mega Corp', 'Zeta Games']); + expect(all[0]).toEqual({ id: expect.any(Number), name: 'Alpha Studios' }); + }); + + it('returns empty array when no publishers exist', async () => { + const all = await getAllPublishers(db); + expect(all).toEqual([]); + }); + + it('returns only id and name fields', async () => { + await db.insert(publishers).values({ name: 'Test Publisher', description: 'A test publisher' }); + + const all = await getAllPublishers(db); + + expect(all).toHaveLength(1); + expect(all[0]).toEqual({ id: expect.any(Number), name: 'Test Publisher' }); + expect(all[0]).not.toHaveProperty('description'); + }); +}); diff --git a/src/lib/publishers.ts b/src/lib/publishers.ts new file mode 100644 index 0000000..12723ed --- /dev/null +++ b/src/lib/publishers.ts @@ -0,0 +1,31 @@ +/** + * Data-access helpers for publisher summary records used by Astro pages. + */ + +import { asc } from 'drizzle-orm'; +import type { Database } from './db'; +import { publishers } from '../../db/schema'; +import type { Publisher } from '../types/game'; + +type PublisherSummaryRow = { + id: number; + name: string; +}; + +/** + * Returns all publishers ordered by name. + * + * @param db - Drizzle database client. + * @returns A list of publisher summaries including only `id` and `name`. + */ +export async function getAllPublishers(db: Database): Promise { + const rows = await db + .select({ id: publishers.id, name: publishers.name }) + .from(publishers) + .orderBy(asc(publishers.name)); + + return rows.map((row: PublisherSummaryRow) => ({ + id: row.id, + name: row.name, + })); +} diff --git a/src/pages/index.astro b/src/pages/index.astro index 5ad3cfa..0c3615d 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -3,12 +3,17 @@ import Layout from '../layouts/Layout.astro'; import GameCard from '../components/GameCard.astro'; import PageHero from '../components/PageHero.astro'; import EmptyState from '../components/EmptyState.astro'; +import FilterControls from '../components/FilterControls.astro'; import { getDatabase } from '../lib/db'; import { getAllGames } from '../lib/games'; +import { getAllCategories } from '../lib/categories'; +import { getAllPublishers } from '../lib/publishers'; export const prerender = true; const games = await getAllGames(getDatabase()); +const categories = await getAllCategories(getDatabase()); +const publishers = await getAllPublishers(getDatabase()); --- @@ -18,6 +23,8 @@ const games = await getAllGames(getDatabase()); subtitle="Find your next game! And maybe even back one! Explore our collection!" /> + +

Featured Games