Thank you for investing your time in contributing to our project! ✨.
Read our Code of Conduct to keep our community approachable and respectable.
In this guide you will get an overview of the contribution workflow from opening an issue, creating a PR, reviewing, and merging the PR.
To get an overview of the project, read the README. Here are some resources to help you get started with open source contributions:
- Finding ways to contribute to open source on GitHub
- Set up Git
- GitHub flow
- Collaborating with pull requests
- How to Write GitHub Markdown.
If you spot a problem with the docs, search if an issue already exists. If a related issue doesn't exist, you can open a new issue using a relevant issue form.
Scan through our existing issues to find one that interests you. You can narrow down the search using labels
as filters. See Labels for more information. As a general rule, we don’t assign issues to anyone. If you find an issue to work on, you are welcome to open a PR with a fix.
We encourage contributors to practice Test Driven Development (TDD) when working on cuttle.cards, because it can save an enormous amount of time while increasing everyone's confidence that the application does what it's supposed to. By utilizing the existing testing infrastructure, you can quickly and automatically do things like:
- Sign-up two accounts and drop them into a game
- Load the game into a specific state i.e. putting the cards wherever you want
- Make arbitrary chains of moves on behalf of both players
- Assert the full state of the game (where the relevant cards are) and more.
The general idea behind Test Driven Development is to write/modify the tests before making changes to the application. This lets you clearly define what the application is supposed to do before changing things, so that you'll know with confidence when things work correctly. TDD takes practice, and it's not required to contribute, but we are happy to help you practice it and once you get going with testing, you'll see what an enormous Quality of Life improvement it can make to your developer experience.
Click the PENCIL icon top right of any docs page to make small changes such as a typo, sentence fix, or a broken link. This takes you a file editor where you can make your changes and create a pull request for a review.
-
Fork the repository.
- Using the command line:
- Fork the repo so that you can make your changes without affecting the original project until you're ready to merge them.
-
Install or update to Node.js v16.
At the root directory, use the cmd
npm ci
-
Set up Cypress.io, our end-to-end testing framework, please follow the installation guide according to your operating system.
-
For seeding the database, here's a quick guide:
Recommended Way - Please see Test-Driven Development
While booted in development mode (the default), you can make requests to
/test/loadSeasonFixture
and/test/loadMatchFixtures
to seed records into those tables.To delete data from the database, you can make a request
/test/wipeDatabase
to your local server which will wipe all records. -
Create a working branch by
git checkout -b feature/[your feature or issue number]
orgit checkout -b bug/[your fix or issue number]
and start with your changes!
The easiest way to seed data is using test code. The existing in-game end-to-end tests (found in the /tests/e2e/specs/in-game/*.spec.js
files) generally call the cy.setupGameAsP0()
or cy.setupGameAsP1()
are imported from tests/e2e/support/helpers.js
. These test helpers will run inside the beforeEach()
hooks that run before each test. This will automatically:
- Sign up and authenticate two accounts
- Create and join a game as both players
- Ready up to start that game
- Log success and continue to the next test commands once the game has loaded
This is much faster than setting up a game by hand, and it pairs very well with the custom cypress command cy.loadGameFixture()
which allows you to programmatically load the game into a specific state by specifying where you would like specific cards to be place e.g.
cy.loadGameFixture({
p0Hand: [Card.ACE_OF_CLUBS, Card.ACE_OF_SPADES, Card.SEVEN_OF_CLUBS],
p0Points: [Card.TWO_OF_CLUBS, Card.TEN_OF_HEARTS],
p0FaceCards: [Card.KING_OF_SPADES],
p1Hand: [Card.TEN_OF_CLUBS, Card.TEN_OF_SPADES],
p1Points: [Card.SIX_OF_HEARTS, Card.ACE_OF_DIAMONDS],
p1FaceCards: [Card.QUEEN_OF_HEARTS],
topCard: Card.FIVE_OF_DIAMONDS,
secondCard: Card.EIGHT_OF_SPADES,
scrap: [Card.TWO_OF_HEARTS, Card.FOUR_OF_CLUBS],
});
You can then make moves on behalf of the player by clicking on various elements using cy.get('<some-selector>').click()
. Various elements (like cards in different places) have data-* selectors applied to them in the template. Check the templates of the component(s) you're testing to see the exact selectors, but as a general rule, cards are given attributes of the form: data-<which-player>-<which-localtion>-card=<rank>_<suit>
(ranks start at 1 and suits start at 0) and move choices are given attributes of the form data-move-choice=<move-name>
.
So in the above example you could scuttle p1's six of hearts using p0's seven of clubs (if you are p0) with:
cy.get('[data-player-hand-card=7_0').click(); // Click the 7 of clubs in the player's hand
cy.get('[data-move-choice=scuttle]').click(); // Choose to scuttle
cy.get('[data-opponent-point-card=6_2]').click(); // Click opponent's 6 of hearts to select it for scuttling
You can then make moves on behalf of the opponent using custom cypress commands that will request any particular move e.g. cy.drawCardOpponent();
or cy.playPointsOpponent(Card.TEN_OF_CLUBS);
Lastly, you can use the assertGameState(playerNumber, fixtureObject)
helper to verify that the resulting game state matches the specified fixture same shape as the input to loadGameFixture()
, after specifying the player number (0 for p0, 1 for p1) of the which player's perspective we are testing from.
For other tests, it may be valuable to seed the database directly with records from fixture data. If you look at tests/e2e/specs/out-of-game/stats.spec.js
you'll find the tests for the stats page. These tests already import fixture data from tests/e2e/fixtures/statsFixtures.js
and use a custom cypress command to request those endpoints and seed that data into the database beforeEach
test.
Once your changes are ready, don't forget run the linter npm run lint:fix
so the code is automatically formatted. Then you will need to run the test suites so that your changes are not breaking them. You may also create new tests or update any tests due to new behavioral changes.
To run the test suite, start by running the cmd npm run start:server
. This will start the node server. Then you can run either npm run e2e:client
or npm run e2e:gui
. After all the tests has pass, you can self-review the changes yourself to speed up the review process:zap:.
Now, commit the changes once you are happy with them.
When you're finished with the changes, create a pull request, also known as a PR.
- Fill the "Ready for review" template so that we can review your PR. This template helps reviewers understand your changes as well as the purpose of your pull request.
- Don't forget to link PR to issue if you are solving one.
- Enable the checkbox to allow maintainer edits so the branch can be updated for a merge. Once you submit your PR, a team member will review your proposal. We may ask questions or request for additional information.
- We may ask for changes to be made before a PR can be merged, either using suggested changes or pull request comments. You can apply suggested changes directly through the UI. You can make any other changes in your fork, then commit them to your branch.
- As you update your PR and apply changes, mark each conversation as resolved.
- If you run into any merge issues, checkout this git tutorial to help you resolve merge conflicts and other issues.
Congratulations 🎉🎉 The Cuttle Cards team thanks you ✨.
Once your PR is merged, your contributions will be publicly visible on the Cuttle Cards repository and automatically deployed to www.cuttle.cards.
You are now a Cuttle Cards Contributor!