-
Notifications
You must be signed in to change notification settings - Fork 3.4k
feat(driver): add timeout diagnostics and async vite loader #33022
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
lucgonp
wants to merge
28
commits into
cypress-io:develop
Choose a base branch
from
lucgonp:feat/vite-with-timeout-backup
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+973
−23
Open
Changes from 8 commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
65267ae
feat(vite-dev-server): migrate to async fs operations for better perf…
lucgonp 8103f1c
fix: use promisify for better Node.js compatibility
lucgonp 5383e8d
fix: implement lazy promise initialization and fix lint issues
lucgonp a388894
fix: add proper error handling to lazy promise initialization
lucgonp 50d5920
feat: add intelligent timeout diagnostics system
lucgonp 2b93731
fix: address Cursor Bot security and correctness issues
lucgonp 3544244
fix(driver): preserve literal selectors in diagnostics
lucgonp 5e45cf4
fix(vite-dev-server): avoid leading whitespace when injecting loader
lucgonp d705572
fix(driver): escape double quotes in diagnostics
lucgonp 1d6787c
Merge branch 'develop' into feat/vite-with-timeout-backup
lucgonp 5577760
docs(cli): add timeout diagnostics changelog entry
lucgonp 48815f6
Merge branch 'develop' into feat/vite-with-timeout-backup
lucgonp bae73cd
Merge branch 'develop' into feat/vite-with-timeout-backup
lucgonp 2e336ee
Merge branch 'develop' into feat/vite-with-timeout-backup
lucgonp 40cfe95
Merge branch 'develop' into feat/vite-with-timeout-backup
lucgonp 413b58e
chore: update timeout diagnostics documentation for clarity
lucgonp 4706662
feat: enhance timeout suggestions for child commands in TimeoutDiagno…
lucgonp 95ba223
fix: improve selector escaping in TimeoutDiagnostics for better handl…
lucgonp 7ae0cd7
Merge branch 'develop' into feat/vite-with-timeout-backup
lucgonp 88addf9
chore: update release date for version 15.7.1 in CHANGELOG.md
lucgonp 99d2488
chore: update release date for version 15.7.1 in CHANGELOG.md to pending
lucgonp 2e9247e
chore: update release date for version 15.7.1 in CHANGELOG.md
lucgonp 8d8df7e
fix: correct escape sequence handling in escapeSelector method
lucgonp 33730de
Merge branch 'develop' into feat/vite-with-timeout-backup
lucgonp 2d09dc4
chore: update release date for version 15.7.1 in CHANGELOG.md
lucgonp ae6f593
Merge branch 'feat/vite-with-timeout-backup' of https://github.com/lu…
lucgonp 763fd5e
chore: update CHANGELOG.md for version 15.8.0 and enhance parseChange…
lucgonp 8adeec5
Merge branch 'develop' into feat/vite-with-timeout-backup
lucgonp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
198 changes: 198 additions & 0 deletions
198
packages/driver/src/cypress/TIMEOUT_DIAGNOSTICS_README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,198 @@ | ||
| # Timeout Diagnostics - Smart Error Messages | ||
|
|
||
| ## 🎯 Objetivo | ||
|
|
||
| Melhorar dramaticamente a experiência do desenvolvedor ao lidar com erros de timeout no Cypress, fornecendo **sugestões contextuais e acionáveis** baseadas na análise do contexto do erro. | ||
|
|
||
| ## 🚀 Motivação | ||
|
|
||
| Erros de timeout são extremamente comuns em testes Cypress, mas as mensagens tradicionais são genéricas: | ||
|
|
||
| ``` | ||
| cy.get() timed out waiting 4000ms | ||
| ``` | ||
|
|
||
| Com este sistema, os desenvolvedores recebem diagnósticos inteligentes: | ||
|
|
||
| ``` | ||
| cy.get() timed out waiting 4000ms | ||
|
|
||
| 🔍 Diagnostic Suggestions: | ||
|
|
||
| 1. The selector appears to target dynamic/loading content | ||
| a) Wait for the loading state to complete: cy.get('.loading-spinner').should('not.exist') | ||
| b) Consider using data-cy attributes instead of class names that indicate loading states | ||
| c) Use cy.intercept() to wait for the API request that populates this content | ||
| 📚 Learn more: https://on.cypress.io/best-practices#Selecting-Elements | ||
|
|
||
| 2. 8 network requests are still pending | ||
| a) Wait for specific API calls to complete using cy.intercept() | ||
| b) Consider increasing the timeout if the requests are expected to be slow | ||
| c) Check if some requests are failing or hanging in the Network tab | ||
| d) Example: cy.intercept("GET", "/api/data").as("getData"); cy.wait("@getData") | ||
| 📚 Learn more: https://on.cypress.io/intercept | ||
| ``` | ||
|
|
||
| ## ✨ Funcionalidades | ||
|
|
||
| ### 1. **Detecção de Seletores Problemáticos** | ||
| - Identifica seletores que apontam para conteúdo dinâmico (loading, spinner, skeleton) | ||
| - Detecta seletores complexos e frágeis | ||
| - Alerta sobre IDs dinâmicos (ex: `#user-12345`) | ||
|
|
||
| ### 2. **Análise de Problemas de Rede** | ||
| - Detecta múltiplas requisições pendentes | ||
| - Identifica timeouts longos que sugerem operações assíncronas | ||
| - Sugere uso de `cy.intercept()` para melhor controle | ||
|
|
||
| ### 3. **Diagnóstico de Animações** | ||
| - Identifica quando animações estão causando delays | ||
| - Sugere configurações para desabilitar animações em testes | ||
|
|
||
| ### 4. **Detecção de Mutações Excessivas do DOM** | ||
| - Identifica quando o DOM está mudando rapidamente | ||
| - Sugere esperar por estabilização antes de interagir | ||
|
|
||
| ### 5. **Sugestões Específicas por Comando** | ||
| - Sugestões customizadas para cada tipo de comando (`get`, `click`, `type`, etc.) | ||
| - Links para documentação relevante | ||
|
|
||
| ## 📦 Estrutura | ||
|
|
||
| ``` | ||
| packages/driver/src/cypress/ | ||
| └── timeout_diagnostics.ts # Lógica principal | ||
|
|
||
| packages/driver/test/unit/cypress/ | ||
| └── timeout_diagnostics.spec.ts # Testes unitários | ||
| ``` | ||
|
|
||
| ## 🔧 API | ||
|
|
||
| ```typescript | ||
| import { TimeoutDiagnostics } from './timeout_diagnostics' | ||
|
|
||
| // Analisar contexto e obter sugestões | ||
| const suggestions = TimeoutDiagnostics.analyze({ | ||
| command: 'get', | ||
| selector: '.loading-spinner', | ||
| timeout: 4000, | ||
| networkRequests: 5, | ||
| animationsRunning: true, | ||
| }) | ||
|
|
||
| // Formatar sugestões para exibição | ||
| const formatted = TimeoutDiagnostics.formatSuggestions(suggestions) | ||
|
|
||
| // Enriquecer mensagem de erro existente | ||
| const enhanced = TimeoutDiagnostics.enhanceTimeoutError( | ||
| 'cy.get() timed out', | ||
| context | ||
| ) | ||
| ``` | ||
|
|
||
| ## 🎨 Exemplos de Uso | ||
|
|
||
| ### Exemplo 1: Conteúdo Dinâmico | ||
| ```typescript | ||
| // Teste que falha | ||
| cy.get('.loading-spinner').click() | ||
|
|
||
| // Erro melhorado sugere: | ||
| // "Wait for the loading state to complete: | ||
| // cy.get('.loading-spinner').should('not.exist')" | ||
| ``` | ||
|
|
||
| ### Exemplo 2: Problemas de Rede | ||
| ```typescript | ||
| // Teste aguardando resposta API | ||
| cy.get('.user-data').should('be.visible') | ||
|
|
||
| // Erro melhorado sugere: | ||
| // "Use cy.intercept() to wait for the specific request: | ||
| // cy.intercept('GET', '/api/users').as('getUsers') | ||
| // cy.wait('@getUsers')" | ||
| ``` | ||
|
|
||
| ### Exemplo 3: Animações | ||
| ```typescript | ||
| // Elemento animando quando clica | ||
| cy.get('.modal-button').click() | ||
|
|
||
| // Erro melhorado sugere: | ||
| // "Disable animations: .click({ waitForAnimations: false }) | ||
| // Or globally: Cypress.config('animationDistanceThreshold', 0)" | ||
| ``` | ||
|
|
||
| ## 🔮 Integração Futura | ||
|
|
||
| Para integrar completamente no Cypress, seria necessário: | ||
|
|
||
| 1. **Modificar `error_utils.ts`** para capturar contexto adicional durante timeouts | ||
| 2. **Coletar métricas** de rede, DOM e animações durante execução do comando | ||
| 3. **Integrar na pipeline de erro** existente do Cypress | ||
| 4. **Adicionar configuração** para habilitar/desabilitar diagnósticos | ||
|
|
||
| ```typescript | ||
| // Exemplo de integração em error_utils.ts | ||
| import TimeoutDiagnostics from './timeout_diagnostics' | ||
|
|
||
| const createTimeoutError = (cmd, ms) => { | ||
| const context = { | ||
| command: cmd.get('name'), | ||
| selector: cmd.get('selector'), | ||
| timeout: ms, | ||
| networkRequests: getNetworkMonitor().pendingCount(), | ||
| animationsRunning: hasRunningAnimations(), | ||
| domMutations: getDOMMutationCount(), | ||
| } | ||
|
|
||
| const baseMessage = `cy.${cmd.get('name')}() timed out waiting ${ms}ms` | ||
| return TimeoutDiagnostics.enhanceTimeoutError(baseMessage, context) | ||
| } | ||
| ``` | ||
|
|
||
| ## 📊 Benefícios | ||
|
|
||
| 1. **Reduz tempo de debugging**: Desenvolvedores identificam problemas mais rapidamente | ||
| 2. **Educação inline**: Ensina melhores práticas durante o desenvolvimento | ||
| 3. **Menos frustração**: Erros mais claros = desenvolvedores mais felizes | ||
| 4. **Reduz issues no GitHub**: Menos perguntas sobre "por que meu teste timeout?" | ||
| 5. **Melhora adoção**: Desenvolvedores iniciantes aprendem mais rápido | ||
|
|
||
| ## 🧪 Testes | ||
|
|
||
| Execute os testes unitários: | ||
|
|
||
| ```bash | ||
| cd packages/driver | ||
| yarn test timeout_diagnostics.spec.ts | ||
| ``` | ||
|
|
||
| Cobertura inclui: | ||
| - ✅ Detecção de todos os tipos de problemas | ||
| - ✅ Formatação de mensagens | ||
| - ✅ Casos extremos e edge cases | ||
| - ✅ Combinação de múltiplos diagnósticos | ||
|
|
||
| ## 🚀 Próximos Passos | ||
|
|
||
| 1. ✅ Criar módulo de diagnósticos com testes | ||
| 2. ⏳ Integrar com sistema de erros existente | ||
| 3. ⏳ Adicionar coleta de métricas de contexto | ||
| 4. ⏳ Criar configuração para habilitar/desabilitar | ||
| 5. ⏳ Adicionar mais padrões e sugestões baseado em feedback | ||
| 6. ⏳ Documentação para usuários finais | ||
|
|
||
| ## 🤝 Contribuindo | ||
|
|
||
| Este é um sistema extensível. Para adicionar novos diagnósticos: | ||
|
|
||
| 1. Adicione padrão em `COMMON_PATTERNS` | ||
| 2. Crie método `analyze*Issues()` | ||
| 3. Adicione testes correspondentes | ||
| 4. Documente o novo diagnóstico | ||
|
|
||
| ## 📝 Licença | ||
|
|
||
| MIT - Consistente com o projeto Cypress | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.