{"id":30184408,"url":"https://github.com/nextlevelshit/client-e2e","last_synced_at":"2025-08-12T12:07:48.983Z","repository":{"id":302143746,"uuid":"976587543","full_name":"nextlevelshit/client-e2e","owner":"nextlevelshit","description":null,"archived":false,"fork":false,"pushed_at":"2025-07-03T16:54:49.000Z","size":44,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-03T17:24:30.530Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/nextlevelshit.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,"zenodo":null}},"created_at":"2025-05-02T11:30:14.000Z","updated_at":"2025-07-03T16:54:52.000Z","dependencies_parsed_at":"2025-07-03T17:24:54.214Z","dependency_job_id":null,"html_url":"https://github.com/nextlevelshit/client-e2e","commit_stats":null,"previous_names":["nextlevelshit/2025-dhbw-client-e2e","nextlevelshit/client-e2e"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nextlevelshit/client-e2e","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextlevelshit%2Fclient-e2e","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextlevelshit%2Fclient-e2e/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextlevelshit%2Fclient-e2e/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextlevelshit%2Fclient-e2e/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nextlevelshit","download_url":"https://codeload.github.com/nextlevelshit/client-e2e/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nextlevelshit%2Fclient-e2e/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270057812,"owners_count":24519531,"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","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-08-12T12:07:48.246Z","updated_at":"2025-08-12T12:07:48.975Z","avatar_url":"https://github.com/nextlevelshit.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cypress E2E Client Testing\n\nLearn modern end-to-end testing with Cypress using ES6 modules and best practices.\nThis workshop follows the same architectural patterns as our [Express Cache API](https://github.com/nextlevelshit/node-cache-api).\n\n## TL;DR\n\n```bash\nnpm install\nnpm run open   # Interactive development\nnpm run test   # Headless execution\n```\n\n## Architecture Overview\n\n```\ncypress/\n├── e2e/                      # Example test scenarios\n│   ├── calculator.cy.js      # Network interception patterns\n│   ├── chess.cy.js           # State management \u0026 cookie handling\n│   ├── musicca.cy.js         # Virtual Piano\n│   ├── node-api.cy.js        # Node.js API testing\n│   ├── patternsketch.cy.js   # Online Drum Machine Pattern Sketch\n│   └── todo.cy.js            # CRUD operations (template)\n├── fixtures/                 # Test data and configuration\n│   ├── credentials.json      # Placeholder for auth credentials\n│   └── userSettings.json     # Placeholder for user preferences\n├── plugins/                  # Custom Cypress plugins\n├── support/\n│   ├── commands.js           # Custom Cypress commands\n│   └── e2e.js                # Global setup\n└── cypress.config.mjs        # ES6 configuration\n```\n\n## Key Characteristics\n\n- **Real browser** - actual Chromium/Firefox instance\n- **Real DOM** - genuine user interactions (clicks, typing, scrolling)\n- **Real rendering** - CSS, JavaScript, async operations\n- **Cross-origin requests** - client ↔ server communication\n- **User perspective** - exactly what users see and do\n\n## Key Patterns\n\n### 1. Modern ES6 Configuration\n\n```javascript\n// cypress.config.mjs - ES6 style\nimport { defineConfig } from \"cypress\";\n\nexport default defineConfig({\n  e2e: {\n    baseUrl: \"https://your-app.com\",\n    setupNodeEvents(on, config) {\n      // Custom tasks here\n    },\n  },\n});\n```\n\n### 2. Network Interception \u0026 Response Validation\n\n```javascript\n// Real-world API testing from calculator.cy.js\nit(\"should perform basic math\", () =\u003e {\n  cy.intercept(\"/calc\", (req) =\u003e {\n    // Mock or modify requests/responses\n  }).as(\"calcRequest\");\n\n  // Perform UI actions\n  // ...\n\n  // Validate network response\n  cy.wait(\"@calcRequest\").then(({ response }) =\u003e {\n    expect(response.body.status).to.equal(\"ok\");\n    expect(response.body.results[0].in).to.equal(\"2+3\");\n    expect(response.body.results[0].out).to.equal(\"5\");\n  });\n});\n```\n\n### 3. State Management \u0026 Session Handling\n\n```javascript\n// Reproducible test state from chess.cy.js\nbeforeEach(() =\u003e {\n  // Full state reset for consistent tests\n  cy.clearAllCookies();\n  cy.clearAllLocalStorage();\n  cy.clearAllSessionStorage();\n\n  cy.visit(\"https://www.chess.com/play/online\");\n\n  // Handle dynamic consent dialogs\n  cy.get(\"#onetrust-reject-all-handler\", { timeout: 10_000 }).click();\n});\n```\n\n### 4. Fixture-Driven Testing\n\n```javascript\n// Use fixtures for test data management\ncy.fixture(\"credentials\").then((creds) =\u003e {\n  cy.login(creds.valid.email, creds.valid.password);\n});\n\n// Multiple fixtures for different scenarios\ncy.fixture(\"userSettings\").then((settings) =\u003e {\n  cy.configureUserPreferences(settings.theme, settings.language);\n});\n```\n\n### 5. Custom Commands\n\n```javascript\n// cypress/support/commands.js\nCypress.Commands.add(\"login\", (email, password) =\u003e {\n  cy.get(\"[data-cy=email]\").type(email);\n  cy.get(\"[data-cy=password]\").type(password);\n  cy.get(\"[data-cy=submit]\").click();\n});\n```\n\n## API Testing Integration\n\nTest your Cache API using the hosted GUI interface:\n\n**Live Demo**: https://nextlevelshit.github.io/node-cache-api/\n\n```javascript\n// Test your local API through the hosted interface\ndescribe(\"Cache API Integration\", () =\u003e {\n  beforeEach(() =\u003e {\n    cy.visit(\"https://nextlevelshit.github.io/node-cache-api/\");\n  });\n\n  it(\"should perform CRUD operations\", () =\u003e {\n    // Test CREATE operation\n    cy.get(\"#postData\").type('{\"test\": \"data\"}');\n    cy.get(\"button\").contains(\"Create Item\").click();\n\n    // Verify success response\n    cy.get(\"#postResponse\")\n      .should(\"be.visible\")\n      .and(\"contain\", \"Item created successfully\");\n\n    // Test READ operation\n    cy.get(\"#getKey\").type(\"generated-key-from-create\");\n    cy.get(\"button\").contains(\"Fetch Item\").click();\n\n    // Verify data retrieval\n    cy.get(\"#getResponse\")\n      .should(\"be.visible\")\n      .and(\"contain\", \"Retrieved data\");\n  });\n\n  it(\"should handle API errors gracefully\", () =\u003e {\n    // Test error scenarios\n    cy.get(\"#getKey\").type(\"nonexistent-key\");\n    cy.get(\"button\").contains(\"Fetch Item\").click();\n\n    // Verify error handling\n    cy.get(\"#getResponse\")\n      .should(\"be.visible\")\n      .and(\"have.class\", \"error\")\n      .and(\"contain\", \"Key not found\");\n  });\n});\n```\n\n## Testing Philosophy\n\nFollowing the four-tier testing strategy from our Express API:\n\n1. **Static Analysis** → ESLint for Cypress specs\n2. **Unit Tests** → Individual command testing\n3. **Integration Tests** → Component interaction\n4. **E2E Tests** → Full user journeys ← **You are here**\n\n## Common Patterns\n\n### Error Handling \u0026 Visual Feedback\n\n```javascript\n// Test both success and error states\ncy.get(\"#getResponse\")\n  .should(\"be.visible\")\n  .and(\"have.class\", \"error\") // Visual error styling\n  .and(\"contain\", \"Key not found\"); // Error message content\n```\n\n### Dynamic Content \u0026 Timeouts\n\n```javascript\n// Handle dynamic loading with appropriate timeouts\ncy.get(\"#guest-button\", { timeout: 10_000 }).click();\n```\n\n### Comprehensive Test Scenarios\n\n```javascript\n// Real CRUD testing pattern\nit(\"should handle full CRUD lifecycle\", () =\u003e {\n  // CREATE → READ → UPDATE → DELETE\n  // Each step validates both UI and API responses\n});\n```\n\n## Resources\n\n- [Cypress Best Practices](https://docs.cypress.io/guides/references/best-practices)\n- [ES6 Modules in Cypress](https://docs.cypress.io/guides/references/configuration#module-api)\n- [Network Interception Guide](https://docs.cypress.io/guides/guides/network-requests)\n- [Cache API Live Demo](https://nextlevelshit.github.io/node-cache-api/)\n- [Our Express API Testing Guide](https://github.com/nextlevelshit/node-cache-api/README.md) for comparison\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnextlevelshit%2Fclient-e2e","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnextlevelshit%2Fclient-e2e","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnextlevelshit%2Fclient-e2e/lists"}