

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456# Cypress API Testing Excellence78## Network Interception Mastery9- **Request/Response Mocking**: Control external API responses for reliable testing10- **Network Monitoring**: Track and validate API calls during user interactions11- **Error Simulation**: Test error handling and edge cases12- **Performance Testing**: Monitor response times and optimize user experience1314## Advanced API Interception15```javascript16// ✅ Comprehensive API interception setup17describe('API Integration Tests', () => {18 beforeEach(() => {19 // Set up common API routes20 cy.intercept('GET', '/api/users*', { fixture: 'users.json' }).as('getUsers')21 cy.intercept('POST', '/api/users', { fixture: 'user-created.json' }).as('createUser')22 cy.intercept('PUT', '/api/users/*', { fixture: 'user-updated.json' }).as('updateUser')23 cy.intercept('DELETE', '/api/users/*', { statusCode: 204 }).as('deleteUser')24 })2526 it('should handle complete user CRUD operations', () => {27 // Visit page and wait for initial data load28 cy.visit('/users')29 cy.wait('@getUsers').then((interception) => {30 expect(interception.response.statusCode).to.equal(200)31 expect(interception.response.body).to.have.property('users')32 })3334 // Create new user35 cy.get('[data-cy=add-user-button]').click()36 cy.get('[data-cy=user-form]').within(() => {37 cy.get('[data-cy=first-name]').type('John')38 cy.get('[data-cy=last-name]').type('Doe')39 cy.get('[data-cy=email]').type('john.doe@example.com')40 cy.get('[data-cy=submit-button]').click()41 })4243 cy.wait('@createUser').then((interception) => {44 expect(interception.request.body).to.deep.include({45 firstName: 'John',46 lastName: 'Doe',47 email: 'john.doe@example.com'48 })49 expect(interception.response.statusCode).to.equal(201)50 })5152 // Verify user appears in list53 cy.get('[data-cy=user-list]')54 .should('contain.text', 'John Doe')55 .and('contain.text', 'john.doe@example.com')56 })57})58```5960## Dynamic Response Generation61```javascript62// ✅ Smart response generation based on request63cy.intercept('GET', '/api/users/*', (req) => {64 const userId = req.url.split('/').pop()6566 // Generate different responses based on user ID67 if (userId === '1') {68 req.reply({ fixture: 'admin-user.json' })69 } else if (userId === '404') {70 req.reply({ statusCode: 404, body: { error: 'User not found' } })71 } else {72 req.reply({ fixture: 'regular-user.json' })73 }74}).as('getUser')7576// ✅ Conditional responses based on request data77cy.intercept('POST', '/api/login', (req) => {78 const { email, password } = req.body7980 if (email === 'admin@example.com' && password === 'admin123') {81 req.reply({ fixture: 'admin-login-success.json' })82 } else if (email === 'user@example.com' && password === 'user123') {83 req.reply({ fixture: 'user-login-success.json' })84 } else {85 req.reply({86 statusCode: 401,87 body: { error: 'Invalid credentials' }88 })89 }90}).as('login')9192// ✅ Delayed responses for testing loading states93cy.intercept('GET', '/api/heavy-data', (req) => {94 req.reply({95 fixture: 'large-dataset.json',96 delay: 2000 // 2 second delay97 })98}).as('heavyData')99100cy.visit('/dashboard')101cy.get('[data-cy=loading-spinner]').should('be.visible')102cy.wait('@heavyData')103cy.get('[data-cy=loading-spinner]').should('not.exist')104cy.get('[data-cy=data-table]').should('be.visible')105```106107## Error Handling and Edge Cases108```javascript109// ✅ Network error simulation110describe('Network Error Handling', () => {111 it('should handle server errors gracefully', () => {112 // Simulate 500 server error113 cy.intercept('POST', '/api/submit', {114 statusCode: 500,115 body: { error: 'Internal server error' }116 }).as('serverError')117118 cy.visit('/form-page')119 cy.get('[data-cy=submit-form]').submit()120121 cy.wait('@serverError')122 cy.get('[data-cy=error-notification]')123 .should('be.visible')124 .and('contain.text', 'Something went wrong')125 })126127 it('should handle network connectivity issues', () => {128 // Force network error129 cy.intercept('GET', '/api/data', { forceNetworkError: true }).as('networkError')130131 cy.visit('/dashboard')132 cy.wait('@networkError')133134 cy.get('[data-cy=offline-indicator]').should('be.visible')135 cy.get('[data-cy=retry-button]').should('be.visible')136 })137138 it('should handle timeout scenarios', () => {139 // Simulate very slow response140 cy.intercept('GET', '/api/slow-endpoint', (req) => {141 req.reply({142 fixture: 'data.json',143 delay: 30000 // 30 second delay144 })145 }).as('slowResponse')146147 cy.visit('/page-with-timeout')148149 // Should show timeout message150 cy.get('[data-cy=timeout-message]', { timeout: 35000 })151 .should('be.visible')152 })153})154```155156## API State Management Testing157```javascript158// ✅ Complex state management testing159describe('API State Synchronization', () => {160 beforeEach(() => {161 // Set up realistic API responses162 cy.fixture('shopping-cart.json').as('cartData')163 cy.fixture('products.json').as('productsData')164 })165166 it('should maintain cart state across page navigation', () => {167 // Initial cart state168 cy.intercept('GET', '/api/cart', { body: { items: [], total: 0 } }).as('emptyCart')169170 cy.visit('/shop')171 cy.wait('@emptyCart')172173 // Add item to cart174 cy.intercept('POST', '/api/cart/items', (req) => {175 const newItem = req.body176 req.reply({177 statusCode: 201,178 body: {179 items: [newItem],180 total: newItem.price * newItem.quantity181 }182 })183 }).as('addToCart')184185 cy.get('[data-cy=product-1] [data-cy=add-to-cart]').click()186 cy.wait('@addToCart')187188 // Verify cart updates189 cy.get('[data-cy=cart-count]').should('contain.text', '1')190 cy.get('[data-cy=cart-total]').should('contain.text', '$29.99')191192 // Navigate to different page193 cy.intercept('GET', '/api/cart', '@cartData').as('getCart')194 cy.visit('/profile')195 cy.wait('@getCart')196197 // Verify cart state persists198 cy.get('[data-cy=cart-count]').should('contain.text', '1')199 })200})201```202203## Real-time Features Testing204```javascript205// ✅ WebSocket and real-time feature testing206describe('Real-time Features', () => {207 it('should handle live notifications', () => {208 // Mock WebSocket connection209 cy.visit('/dashboard', {210 onBeforeLoad: (win) => {211 // Mock WebSocket212 const mockSocket = {213 send: cy.stub(),214 close: cy.stub(),215 addEventListener: cy.stub()216 }217218 win.WebSocket = function() {219 return mockSocket220 }221222 // Simulate incoming notification223 setTimeout(() => {224 const notificationEvent = new MessageEvent('message', {225 data: JSON.stringify({226 type: 'notification',227 message: 'New message received',228 timestamp: Date.now()229 })230 })231232 // Trigger event handler if it exists233 if (mockSocket.addEventListener.lastCall) {234 const eventHandler = mockSocket.addEventListener.lastCall.args[1]235 eventHandler(notificationEvent)236 }237 }, 1000)238 }239 })240241 // Verify notification appears242 cy.get('[data-cy=notification-toast]', { timeout: 5000 })243 .should('be.visible')244 .and('contain.text', 'New message received')245 })246247 it('should handle live data updates', () => {248 let updateCount = 0249250 cy.intercept('GET', '/api/live-data', (req) => {251 updateCount++252 req.reply({253 body: {254 value: `Live data update ${updateCount}`,255 timestamp: Date.now()256 }257 })258 }).as('liveData')259260 cy.visit('/live-dashboard')261 cy.wait('@liveData')262263 // Initial data264 cy.get('[data-cy=live-value]')265 .should('contain.text', 'Live data update 1')266267 // Simulate periodic updates268 cy.clock()269 cy.tick(5000) // Fast-forward 5 seconds270271 cy.wait('@liveData')272 cy.get('[data-cy=live-value]')273 .should('contain.text', 'Live data update 2')274 })275})276```277278## Custom API Commands279```javascript280// ✅ Reusable API testing commands (in commands.js)281Cypress.Commands.add('mockApiAuth', (userType = 'user') => {282 const authData = {283 user: { fixture: 'auth-user.json' },284 admin: { fixture: 'auth-admin.json' },285 guest: { statusCode: 401, body: { error: 'Unauthorized' } }286 }287288 cy.intercept('POST', '/api/auth/login', authData[userType]).as('login')289 cy.intercept('GET', '/api/auth/me', authData[userType]).as('getCurrentUser')290 cy.intercept('POST', '/api/auth/refresh', authData[userType]).as('refreshToken')291})292293Cypress.Commands.add('mockCrudApi', (resource, data = {}) => {294 const baseUrl = `/api/${resource}`295296 cy.intercept('GET', `${baseUrl}*`, data.list || { fixture: `${resource}-list.json` }).as(`get${resource}`)297 cy.intercept('POST', baseUrl, data.create || { fixture: `${resource}-created.json` }).as(`create${resource}`)298 cy.intercept('PUT', `${baseUrl}/*`, data.update || { fixture: `${resource}-updated.json` }).as(`update${resource}`)299 cy.intercept('DELETE', `${baseUrl}/*`, data.delete || { statusCode: 204 }).as(`delete${resource}`)300})301302Cypress.Commands.add('waitForApiCall', (alias, expectedData = {}) => {303 cy.wait(alias).then((interception) => {304 expect(interception.response.statusCode).to.be.oneOf([200, 201, 204])305306 if (expectedData.requestBody) {307 expect(interception.request.body).to.deep.include(expectedData.requestBody)308 }309310 if (expectedData.responseBody) {311 expect(interception.response.body).to.deep.include(expectedData.responseBody)312 }313 })314})315316// Usage in tests317describe('Using Custom API Commands', () => {318 beforeEach(() => {319 cy.mockApiAuth('admin')320 cy.mockCrudApi('users')321 })322323 it('should perform user management operations', () => {324 cy.visit('/admin/users')325 cy.waitForApiCall('@getusers')326327 // Create user328 cy.get('[data-cy=create-user]').click()329 cy.get('[data-cy=user-form]').within(() => {330 cy.get('[data-cy=name]').type('New User')331 cy.get('[data-cy=email]').type('new@example.com')332 cy.get('[data-cy=submit]').click()333 })334335 cy.waitForApiCall('@createusers', {336 requestBody: { name: 'New User', email: 'new@example.com' }337 })338 })339})340341```
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| tugkanboz/awesome-cursorrulesexample-structures/cypress/.cursor/rules/testing-fundamentals.mdc · 19 | Cursor rules | testarchtesting-strategysecurity+2 | 62/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/selenium-python/.cursor/rules/page-object-patterns.mdc · 19 | Cursor rules | ui | 54/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/next-js/.cursor/rules/app-router-patterns.mdc · 19 | Cursor rules | styleapido-not | 65/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/react-typescript/.cursor/rules/component-development.mdc · 19 | Cursor rules | teststylearchtypes+1 | 58/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/selenium-python/.cursor/rules/framework-architecture.mdc · 19 | Cursor rules | setuptestlint-formatstyle+3 | 93/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesframeworks/cypress/.cursor/rules/cypress-excellence.mdc · 19 | Cursor rules | testtesting-strategysecurityperformance+1 | 58/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/appium-mobile-test-automation-framework/.cursorrules · 19 | .cursorrules | teststylearchperformance+2 | 56/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/cypress-javascript-test-automation-framework/.cursorrules · 19 | .cursorrules | testlint-formatstylearch+4 | 59/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/k6-performance-test-framework/.cursorrules · 19 | .cursorrules | setupteststylearch+2 | 56/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/playwright-javascript-test-automation-framework/.cursorrules · 19 | .cursorrules | testlint-formatstylearch+3 | 59/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/selenium-net-test-automation-framework/.cursorrules · 19 | .cursorrules | teststylearchdeployment+1 | 56/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/selenium-python-test-automation-framework/.cursorrules · 19 | .cursorrules | testlint-formatstylearch+3 | 59/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/vitest-javascript-unit-test-framework/.cursorrules · 19 | .cursorrules | setupteststylearch+5 | 60/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/webdriverio-javascript-test-automation-framework/.cursorrules · 19 | .cursorrules | testlint-formatstylearch+4 | 69/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesrules/restassured-java-framework/.cursorrules · 19 | .cursorrules | teststylearchsecurity+4 | 56/100 | 13 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/selenium-python/.cursor/rules/test-patterns.mdc · 19 | Cursor rules | teststylearchtesting-strategy+1 | 66/100 | 13 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/tugkanboz-awesome-cursorrules-example-structures-cypress-cursor-rules-api-testing)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.