Cursor rule
example-structures/cypress/.cursor/rules/testing-fundamentals.mdcCore Cypress testing principles — selector strategy, smart waiting, and spec organization. Apply when writing or reviewing Cypress E2E tests.
Cursor rules
Quality
62/100
Scores the file, not the repository.Length
569 words
8 headings · 6 code blocksRepository
18
— · pushed 0 days agoLast changed
2 days ago
First indexed 2 days ago.123456# Cypress Testing Fundamentals78## Core Testing Principles9- **Reliable Selectors**: Use data attributes for stable element identification10- **Smart Waits**: Leverage Cypress's automatic waiting capabilities11- **Test Isolation**: Each test should be independent and repeatable12- **Clear Assertions**: Write descriptive assertions that explain expected behavior1314## Element Selection Excellence15```javascript16// ✅ Best Practice - Use data-cy attributes17cy.get('[data-cy=login-button]').click()18cy.get('[data-cy=username-input]').type('user@example.com')19cy.get('[data-cy=password-input]').type('password123')2021// ✅ Alternative - Use data-testid22cy.get('[data-testid=submit-form]').click()2324// ✅ Accessible selectors25cy.get('[aria-label="Close dialog"]').click()26cy.get('button').contains('Save Changes').click()2728// ❌ Avoid - Brittle CSS selectors29cy.get('.btn-primary.large-button:nth-child(2)').click() // Fragile30cy.get('#dynamic-id-12345').type('text') // IDs may change31```3233## Smart Waiting Strategies34```javascript35// ✅ Wait for element to be visible and interactable36cy.get('[data-cy=submit-button]')37 .should('be.visible')38 .and('not.be.disabled')39 .click()4041// ✅ Wait for specific content42cy.get('[data-cy=user-name]')43 .should('contain.text', 'John Doe')4445// ✅ Wait for element to disappear (loading states)46cy.get('[data-cy=loading-spinner]').should('not.exist')4748// ✅ Wait for API calls to complete49cy.intercept('POST', '/api/users').as('createUser')50cy.get('[data-cy=create-user-form]').submit()51cy.wait('@createUser').then((interception) => {52 expect(interception.response.statusCode).to.equal(201)53})5455// ✅ Custom wait conditions56cy.get('[data-cy=dynamic-content]').should(($el) => {57 expect($el).to.have.length.at.least(1)58 expect($el.text()).to.match(/Expected Pattern/)59})60```6162## Test Structure and Organization63```javascript64describe('User Authentication Flow', () => {65 beforeEach(() => {66 // Set up consistent test state67 cy.visit('/login')68 cy.clearLocalStorage()69 cy.clearCookies()70 })7172 context('Valid Login Scenarios', () => {73 it('should successfully log in with valid credentials', () => {74 // Arrange75 const userData = {76 email: 'test@example.com',77 password: 'validPassword123'78 }7980 // Act81 cy.get('[data-cy=email-input]').type(userData.email)82 cy.get('[data-cy=password-input]').type(userData.password)83 cy.get('[data-cy=login-button]').click()8485 // Assert86 cy.url().should('include', '/dashboard')87 cy.get('[data-cy=welcome-message]')88 .should('be.visible')89 .and('contain.text', 'Welcome back!')9091 // Verify user data is loaded92 cy.get('[data-cy=user-profile]')93 .should('contain.text', userData.email)94 })9596 it('should remember user when "Remember me" is checked', () => {97 cy.get('[data-cy=email-input]').type('test@example.com')98 cy.get('[data-cy=password-input]').type('password123')99 cy.get('[data-cy=remember-me-checkbox]').check()100 cy.get('[data-cy=login-button]').click()101102 // Verify login success103 cy.url().should('include', '/dashboard')104105 // Simulate browser restart by clearing session106 cy.clearCookies({ domain: null })107 cy.visit('/login')108109 // Verify user is still remembered110 cy.get('[data-cy=email-input]')111 .should('have.value', 'test@example.com')112 })113 })114115 context('Invalid Login Scenarios', () => {116 it('should display error for invalid credentials', () => {117 cy.get('[data-cy=email-input]').type('invalid@example.com')118 cy.get('[data-cy=password-input]').type('wrongPassword')119 cy.get('[data-cy=login-button]').click()120121 // Verify error handling122 cy.get('[data-cy=error-message]')123 .should('be.visible')124 .and('contain.text', 'Invalid credentials')125126 // Verify user stays on login page127 cy.url().should('include', '/login')128129 // Verify form state130 cy.get('[data-cy=password-input]').should('have.value', '')131 cy.get('[data-cy=email-input]').should('have.value', 'invalid@example.com')132 })133134 it('should validate required fields', () => {135 // Test empty form submission136 cy.get('[data-cy=login-button]').click()137138 cy.get('[data-cy=email-error]')139 .should('be.visible')140 .and('contain.text', 'Email is required')141142 cy.get('[data-cy=password-error]')143 .should('be.visible')144 .and('contain.text', 'Password is required')145 })146 })147})148```149150## Advanced Assertions151```javascript152// ✅ Multiple assertions in sequence153cy.get('[data-cy=product-card]')154 .should('be.visible')155 .and('contain.text', 'Product Name')156 .and('have.class', 'available')157 .find('[data-cy=price]')158 .should('contain.text', '$29.99')159160// ✅ Custom assertion functions161cy.get('[data-cy=user-list]').should(($list) => {162 expect($list).to.have.length.at.least(1)163 expect($list.find('[data-cy=user-item]')).to.have.length.at.least(5)164165 // Verify each user item has required elements166 $list.find('[data-cy=user-item]').each((index, item) => {167 expect(Cypress.$(item).find('[data-cy=user-name]')).to.exist168 expect(Cypress.$(item).find('[data-cy=user-email]')).to.exist169 })170})171172// ✅ Conditional assertions173cy.get('body').then(($body) => {174 if ($body.find('[data-cy=modal]').length > 0) {175 cy.get('[data-cy=modal-close]').click()176 }177178 cy.get('[data-cy=main-content]').should('be.visible')179})180181// ✅ Retry assertions with custom timeout182cy.get('[data-cy=dynamic-content]', { timeout: 15000 })183 .should('exist')184 .and('not.be.empty')185```186187## Test Data Management188```javascript189// ✅ Fixtures for test data190cy.fixture('users.json').then((users) => {191 const testUser = users.validUser192193 cy.get('[data-cy=email-input]').type(testUser.email)194 cy.get('[data-cy=password-input]').type(testUser.password)195})196197// ✅ Dynamic test data generation198const generateTestUser = () => ({199 email: `test+${Date.now()}@example.com`,200 password: `testPass${Math.random().toString(36).substring(7)}`,201 firstName: 'Test',202 lastName: 'User'203})204205// ✅ Environment-specific data206const getApiUrl = () => {207 const env = Cypress.env('environment') || 'dev'208 const urls = {209 dev: 'https://api-dev.example.com',210 staging: 'https://api-staging.example.com',211 prod: 'https://api.example.com'212 }213 return urls[env]214}215```216217## Performance Considerations218```javascript219// ✅ Efficient element queries220cy.get('[data-cy=main-container]').within(() => {221 // Scope queries to container for better performance222 cy.get('[data-cy=search-input]').type('test query')223 cy.get('[data-cy=search-button]').click()224 cy.get('[data-cy=results-list]').should('exist')225})226227// ✅ Minimize unnecessary operations228cy.visit('/dashboard', {229 onBeforeLoad: (win) => {230 // Disable analytics to speed up tests231 win.analytics = { track: () => {} }232 }233})234235// ✅ Use aliases to avoid re-querying236cy.get('[data-cy=complex-form]').as('mainForm')237cy.get('@mainForm').find('[data-cy=input-field]').type('value')238cy.get('@mainForm').find('[data-cy=submit-button]').click()239```240
Also in tugkanboz/awesome-cursorrules
Diff this repo’s formatsOne 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/api-testing.mdc · 18 | Cursor rules | testtesting-strategyapi | 58/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/appium-mobile-test-automation-framework/.cursorrules · 18 | .cursorrules | teststylearchperformance+2 | 56/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/cypress-javascript-test-automation-framework/.cursorrules · 18 | .cursorrules | testlint-formatstylearch+4 | 59/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/k6-performance-test-framework/.cursorrules · 18 | .cursorrules | setupteststylearch+2 | 56/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/restassured-java-framework/.cursorrules · 18 | .cursorrules | teststylearchsecurity+4 | 56/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/selenium-net-test-automation-framework/.cursorrules · 18 | .cursorrules | teststylearchdeployment+1 | 56/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/selenium-python-test-automation-framework/.cursorrules · 18 | .cursorrules | testlint-formatstylearch+3 | 59/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/webdriverio-javascript-test-automation-framework/.cursorrules · 18 | .cursorrules | testlint-formatstylearch+4 | 69/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/next-js/.cursor/rules/app-router-patterns.mdc · 18 | Cursor rules | styleapido-not | 65/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/react-typescript/.cursor/rules/component-development.mdc · 18 | Cursor rules | teststylearchtypes+1 | 58/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/selenium-python/.cursor/rules/framework-architecture.mdc · 18 | Cursor rules | setuptestlint-formatstyle+3 | 93/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/selenium-python/.cursor/rules/page-object-patterns.mdc · 18 | Cursor rules | ui | 54/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesexample-structures/selenium-python/.cursor/rules/test-patterns.mdc · 18 | Cursor rules | teststylearchtesting-strategy+1 | 66/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesframeworks/cypress/.cursor/rules/cypress-excellence.mdc · 18 | Cursor rules | testtesting-strategysecurityperformance+1 | 58/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/playwright-javascript-test-automation-framework/.cursorrules · 18 | .cursorrules | testlint-formatstylearch+3 | 59/100 | 2 days ago | |
| tugkanboz/awesome-cursorrulesrules/vitest-javascript-unit-test-framework/.cursorrules · 18 | .cursorrules | setupteststylearch+5 | 60/100 | 2 days ago |
Diff against example-structures/cypress/.cursor/rules/api-testing.mdc Diff against rules/appium-mobile-test-automation-framework/.cursorrules Diff against rules/cypress-javascript-test-automation-framework/.cursorrules Diff against rules/k6-performance-test-framework/.cursorrules Diff against rules/restassured-java-framework/.cursorrules Diff against rules/selenium-net-test-automation-framework/.cursorrules Diff against rules/selenium-python-test-automation-framework/.cursorrules Diff against rules/webdriverio-javascript-test-automation-framework/.cursorrules Diff against example-structures/next-js/.cursor/rules/app-router-patterns.mdc Diff against example-structures/react-typescript/.cursor/rules/component-development.mdc Diff against example-structures/selenium-python/.cursor/rules/framework-architecture.mdc Diff against example-structures/selenium-python/.cursor/rules/page-object-patterns.mdc Diff against example-structures/selenium-python/.cursor/rules/test-patterns.mdc Diff against frameworks/cypress/.cursor/rules/cypress-excellence.mdc Diff against rules/playwright-javascript-test-automation-framework/.cursorrules Diff against rules/vitest-javascript-unit-test-framework/.cursorrules
