Zapamtilica is a simple memory game I created recently. In the meantime, I got an idea to automate the process of solving it using Cypress. The script I developed systematically flips the cards, remembers their positions, and finds matching pairs until all cards are matched. I’ll walk you through the script step by step, explaining how it works and how it efficiently solves the puzzle.
Cypress Test Breakdown
You can find the whole test GitHub repository here:
https://github.com/NoToolsNoCraft/Solving-Memory-Game-with-Cypress
Here, you may check out the Cypress test script:
https://github.com/NoToolsNoCraft/Solving-Memory-Game-with-Cypress/blob/main/cypress/e2e/spec.cy.js
Step-by-Step Explanation
1. Setting Up the Test
The script begins by defining a Cypress test case inside describe
and it
blocks. The first lines configure the viewport and navigate to the Zapamtilica game:
cy.viewport(2000, 1300);
cy.visit('https://notoolsnocraft.github.io/zapamtilica.github.io/');
This ensures that the test runs in a properly sized window to view all elements.
2. Using Memory to Track Cards
A memory
object is initialized to store the image source of each flipped card and its corresponding index:
let memory = {};
This helps track which cards have already been seen and allows the script to find matches efficiently. As Cypress opens each card, it memorizes each by adding it to the memory variable. Whenever it finds a pair of a card already opened, it aims toward opening its pair.
3. Recursive Function to Solve the Game
The script defines a function called solveGame()
that is responsible for flipping cards, remembering their positions, and finding matches. It works recursively, continuously checking if the game is solved.
4. Checking if the Game is Solved
The script first checks if the success modal appears:
cy.get('body').then($body => {
if ($body.find('.modal:visible').length > 0) {
cy.get('.modal').should('contain', 'Fenomenalno odrađeno!');
}
If the modal is found, the test confirms that the expected success message is present and stops.
5. Iterating Over Cards
If the game is not solved, the script iterates over all cards:
cy.get('.card-container').each(($card, index) => {
if (!$card.find('.card').first().hasClass('front-correct')) {
cy.wrap($card).click();
cy.wait(300);
It ensures that only unmatched cards are processed to avoid unnecessary clicks.
6. Storing and Matching Cards
Once a card is flipped, the script retrieves its image source:
cy.wrap($card)
.find('.back img')
.invoke('attr', 'src')
.then(src => {
The script then checks whether this image has been seen before:
- If the image was seen on another card, it clicks the matching card to complete the pair.
- If not, it stores the card’s index in memory for future reference.
7. Recursion to Continue the Process
Once all cards have been checked in one iteration, the script waits briefly before calling solveGame()
again:
cy.wait(1000);
solveGame();
This ensures that the game continues until all pairs are matched.
How the Script Solves the Puzzle
- The script flips each card one by one and notes the image.
- If it finds a matching pair, it clicks both cards in sequence.
- It repeats the process until all cards are matched.
- Once all cards are matched, the game displays the success modal, and the script verifies it.
Final word
This Cypress script effectively automates solving the Zapamtilica memory game. By tracking card positions and recursively finding matches, it completes the game efficiently. Even if you’re new to Cypress, this approach demonstrates how automated scripts can interact with web applications, store data dynamically, and solve complex UI challenges.