{"id":15552747,"url":"https://github.com/bahmutov/todo-graphql-example","last_synced_at":"2025-09-28T22:30:35.890Z","repository":{"id":37766917,"uuid":"161506410","full_name":"bahmutov/todo-graphql-example","owner":"bahmutov","description":"Example Todo app on top of json-graphql-server","archived":false,"fork":false,"pushed_at":"2025-01-09T17:15:50.000Z","size":1595,"stargazers_count":28,"open_issues_count":11,"forks_count":13,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-09T18:27:19.524Z","etag":null,"topics":["cypress","cypress-example","cypress-io","example","graphql","todomvc"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bahmutov.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-12T15:19:18.000Z","updated_at":"2024-09-01T20:48:03.000Z","dependencies_parsed_at":"2023-11-09T01:29:33.372Z","dependency_job_id":"1077b2dd-20f2-4ddf-b4a7-9052f69cec07","html_url":"https://github.com/bahmutov/todo-graphql-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Ftodo-graphql-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Ftodo-graphql-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Ftodo-graphql-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bahmutov%2Ftodo-graphql-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bahmutov","download_url":"https://codeload.github.com/bahmutov/todo-graphql-example/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234565653,"owners_count":18853323,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cypress","cypress-example","cypress-io","example","graphql","todomvc"],"created_at":"2024-10-02T14:22:02.631Z","updated_at":"2025-09-28T22:30:35.525Z","avatar_url":"https://github.com/bahmutov.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# todo-graphql-example ![cypress version](https://img.shields.io/badge/cypress-9.7.0-brightgreen)\n[![ci status][gh image]][gh url] [![badges status][badges image]][badges url] [![tags](https://github.com/bahmutov/todo-graphql-example/actions/workflows/tags.yml/badge.svg?branch=master\u0026event=push)](https://github.com/bahmutov/todo-graphql-example/actions/workflows/tags.yml) [![renovate-app badge][renovate-badge]][renovate-app] [![todo-graphql-example](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/count/ahwxj4/master\u0026style=flat\u0026logo=cypress)](https://dashboard.cypress.io/projects/ahwxj4/runs) [![CircleCI](https://circleci.com/gh/bahmutov/todo-graphql-example/tree/master.svg?style=svg)](https://circleci.com/gh/bahmutov/todo-graphql-example/tree/master)\n\n## Blog posts\n\n- [Make GraphQL Calls From Cypress Tests](https://glebbahmutov.com/blog/request-graphql/)\n- [Dynamic API Tests Using Cypress-Each Plugin](https://glebbahmutov.com/blog/dynamic-api-tests-using-cypress-each/)\n- [Refactor Tests To Be Independent And Fast Using Cypress-Each Plugin](https://glebbahmutov.com/blog/refactor-using-each/)\n- [Faster test execution with cypress-grep](https://glebbahmutov.com/blog/cypress-grep-filters/)\n- [Add Timestamps To Cypress](https://glebbahmutov.com/blog/cypress-timestamps/)\n\nRead [Smart GraphQL Stubbing in Cypress](https://glebbahmutov.com/blog/smart-graphql-stubbing/). Note that with the addition of [cy.intercept](https://on.cypress.io/intercept) all extra hacks became unnecessary.\n\n## Videos\n\n- [Toggle Todo When Using GraphQL Calls](https://www.youtube.com/watch?v=QA_moq_Yh5M)\n- [Set GraphQL Network Intercept Alias](https://www.youtube.com/watch?v=jN1vsGGXAjw)\n- [Set GraphQL Operation Name As Custom Header And Use It In cy.intercept](https://www.youtube.com/watch?v=AcU5mkedchM)\n- [Add A New Item By Making GraphQL Call Using cy.request Command](https://www.youtube.com/watch?v=ubnJ9kWD1yQ)\n- [Use Application GraphQL Client To Make Calls From The Cypress Test](https://youtu.be/6ykTS40_scM)\n- [Stub The Initial Data Load Using A Fixture](https://youtu.be/IxgWmzy26gM)\n- [Delete All Items Using GraphQL Client As Part Of Cypress Test](https://www.youtube.com/watch?v=l7E7K7x7V8g)\n- [Directly Spying on GraphQL Calls Made By The Application](https://youtu.be/XadOqS0YNJE)\n- [Dynamic Tests From Cypress.io Fixture File](https://youtu.be/EXVwvJrUGJ8)\n- [Introduction To cypress-data-session Plugin](https://youtu.be/7ipCvJQixI0) using [cypress-data-session](https://github.com/bahmutov/cypress-data-session)\n\n## Cypress tests\n\nAll tests are in the [cypress/integration](./cypress/integration) folder.\n\nBy mocking network calls using [cy.intercept](https://on.cypress.io/intercept) see the [intercept-spec.js](cypress/integration/intercept-spec.js) file.\n\nSpec [client-spec.js](cypress/integration/client-spec.js) is testing making individual GraphQL calls using app's own client.\n\nSpec [ui-spec.js](cypress/integration/ui-spec.js) has simple tests that do not depend on the network, and thus are hard to write.\n\nWe can use [cy.request](https://on.cypress.io/request) command to make GraphQL requests ourselves, see the [request-spec.js](./cypress/integration/request-spec.js) file.\n\nWe can stub the initial items load using a fixture file. See the spec file [fixture-spec.js](./cypress/integration/fixture-spec.js).\n\nWe delete all items in the [delete-spec.js](./cypress/integration/delete-spec.js) test. First we query all todo items, then delete them one by one.\n\nWe can import the list of items from a fixture file [cypress/fixtures/three.json](./cypress/fixtures/three.json) and create a dynamic test for each item, see the spec file [dynamic-spec.js](./cypress/integration/dynamic-spec.js).\n\n## App\n\nStart server with `npm start`. You can find GraphQL playground at `http://localhost:3000`\n\n![App in action](images/app.gif)\n\nExample asking for all todos\n\n```\nquery {\n  allTodos {\n    id,\n    title,\n    completed\n  }\n}\n```\n\nResponse\n\n```json\n{\n  \"data\": {\n    \"allTodos\": [\n      {\n        \"id\": \"1\",\n        \"title\": \"do something\",\n        \"completed\": false\n      },\n      {\n        \"id\": \"2\",\n        \"title\": \"another\",\n        \"completed\": false\n      }\n    ]\n  }\n}\n```\n\nExample creating new todo object\n\n```\nmutation {\n  createTodo(id: 2, title: \"another\", completed: false) {\n    id\n  }\n}\n```\n\nResponse\n\n```json\n{\n  \"data\": {\n    \"createTodo\": {\n      \"id\": \"2\"\n    }\n  }\n}\n```\n\nExample asking for a single todo (notice `id` argument)\n\n```\nquery {\n  Todo(id: 2) {\n    id,\n    title,\n    completed\n  }\n}\n```\n\nResponse\n\n```json\n{\n  \"data\": {\n    \"Todo\": {\n      \"id\": \"2\",\n      \"title\": \"another\",\n      \"completed\": false\n    }\n  }\n}\n```\n\n## Development\n\nBackend is [json-graphql-server](https://github.com/marmelab/json-graphql-server). Front-end React code is in [src](src) folder, modeled after [Getting Started With React And GraphQL](https://medium.com/codingthesmartway-com-blog/getting-started-with-react-and-graphql-395311c1e8da) post.\n\nTo start the applications and open Cypress\n\n```shell\n$ npm run dev\n# starts the API, starts the web application\n# when the application responds\n# opens Cypress test runner\n```\n\nTo start the application and run headless Cypress tests\n\n```shell\n$ npm run local\n```\n\n## Types\n\nLook at [cypress/jsconfig.json](./cypress/jsconfig.json) that loads all 3rd party types, and includes the link to [cypress/support/index.d.ts](./cypress/support/index.d.ts) where I describe the type for custom command `cy.createTodos` defined in [cypress/support/index.js](./cypress/support/index.js).\n\n## About me\n\n- [@bahmutov](https://twitter.com/bahmutov)\n- [glebbahmutov.com](https://glebbahmutov.com)\n- [blog](https://glebbahmutov.com/blog)\n- [videos](https://www.youtube.com/glebbahmutov)\n- [presentations](https://slides.com/bahmutov)\n- [cypress.tips](https://cypress.tips)\n\n[renovate-badge]: https://img.shields.io/badge/renovate-app-blue.svg\n[renovate-app]: https://renovateapp.com/\n[badges image]: https://github.com/bahmutov/todo-graphql-example/workflows/badges/badge.svg?branch=master\n[badges url]: https://github.com/bahmutov/todo-graphql-example/actions\n[gh image]: https://github.com/bahmutov/todo-graphql-example/workflows/ci/badge.svg?branch=master\n[gh url]: https://github.com/bahmutov/todo-graphql-example/actions\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahmutov%2Ftodo-graphql-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbahmutov%2Ftodo-graphql-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbahmutov%2Ftodo-graphql-example/lists"}