@jhl8041/dooray-mcp 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/bmad_agent_bmad-master.md +14 -0
- package/.claude/commands/bmad_bmm_agent_analyst.md +14 -0
- package/.claude/commands/bmad_bmm_agent_architect.md +14 -0
- package/.claude/commands/bmad_bmm_agent_dev.md +14 -0
- package/.claude/commands/bmad_bmm_agent_pm.md +14 -0
- package/.claude/commands/bmad_bmm_agent_quick-flow-solo-dev.md +14 -0
- package/.claude/commands/bmad_bmm_agent_sm.md +14 -0
- package/.claude/commands/bmad_bmm_agent_tea.md +14 -0
- package/.claude/commands/bmad_bmm_agent_tech-writer_tech-writer.md +14 -0
- package/.claude/commands/bmad_bmm_agent_ux-designer.md +14 -0
- package/.claude/commands/bmad_bmm_check-implementation-readiness.md +5 -0
- package/.claude/commands/bmad_bmm_code-review.md +13 -0
- package/.claude/commands/bmad_bmm_correct-course.md +13 -0
- package/.claude/commands/bmad_bmm_create-architecture.md +5 -0
- package/.claude/commands/bmad_bmm_create-epics-and-stories.md +5 -0
- package/.claude/commands/bmad_bmm_create-excalidraw-dataflow.md +13 -0
- package/.claude/commands/bmad_bmm_create-excalidraw-diagram.md +13 -0
- package/.claude/commands/bmad_bmm_create-excalidraw-flowchart.md +13 -0
- package/.claude/commands/bmad_bmm_create-excalidraw-wireframe.md +13 -0
- package/.claude/commands/bmad_bmm_create-prd.md +5 -0
- package/.claude/commands/bmad_bmm_create-product-brief.md +5 -0
- package/.claude/commands/bmad_bmm_create-story.md +13 -0
- package/.claude/commands/bmad_bmm_create-ux-design.md +5 -0
- package/.claude/commands/bmad_bmm_dev-story.md +13 -0
- package/.claude/commands/bmad_bmm_document-project.md +13 -0
- package/.claude/commands/bmad_bmm_quick-dev.md +5 -0
- package/.claude/commands/bmad_bmm_quick-spec.md +5 -0
- package/.claude/commands/bmad_bmm_research.md +5 -0
- package/.claude/commands/bmad_bmm_retrospective.md +13 -0
- package/.claude/commands/bmad_bmm_sprint-planning.md +13 -0
- package/.claude/commands/bmad_bmm_sprint-status.md +13 -0
- package/.claude/commands/bmad_bmm_testarch-atdd.md +13 -0
- package/.claude/commands/bmad_bmm_testarch-automate.md +13 -0
- package/.claude/commands/bmad_bmm_testarch-ci.md +13 -0
- package/.claude/commands/bmad_bmm_testarch-framework.md +13 -0
- package/.claude/commands/bmad_bmm_testarch-nfr.md +13 -0
- package/.claude/commands/bmad_bmm_testarch-test-design.md +13 -0
- package/.claude/commands/bmad_bmm_testarch-test-review.md +13 -0
- package/.claude/commands/bmad_bmm_testarch-trace.md +13 -0
- package/.claude/commands/bmad_brainstorming.md +5 -0
- package/.claude/commands/bmad_editorial-review-prose.md +9 -0
- package/.claude/commands/bmad_editorial-review-structure.md +10 -0
- package/.claude/commands/bmad_help.md +9 -0
- package/.claude/commands/bmad_index-docs.md +9 -0
- package/.claude/commands/bmad_party-mode.md +5 -0
- package/.claude/commands/bmad_review-adversarial-general.md +9 -0
- package/.claude/commands/bmad_shard-doc.md +9 -0
- package/_bmad/_config/agent-manifest.csv +11 -0
- package/_bmad/_config/agents/bmm-analyst.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-architect.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-dev.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-pm.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-quick-flow-solo-dev.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-sm.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-tea.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-tech-writer.customize.yaml +41 -0
- package/_bmad/_config/agents/bmm-ux-designer.customize.yaml +41 -0
- package/_bmad/_config/agents/core-bmad-master.customize.yaml +41 -0
- package/_bmad/_config/bmad-help.csv +40 -0
- package/_bmad/_config/files-manifest.csv +281 -0
- package/_bmad/_config/manifest.yaml +21 -0
- package/_bmad/_config/task-manifest.csv +9 -0
- package/_bmad/_config/tool-manifest.csv +1 -0
- package/_bmad/_config/workflow-manifest.csv +32 -0
- package/_bmad/bmm/agents/analyst.md +76 -0
- package/_bmad/bmm/agents/architect.md +58 -0
- package/_bmad/bmm/agents/dev.md +69 -0
- package/_bmad/bmm/agents/pm.md +72 -0
- package/_bmad/bmm/agents/quick-flow-solo-dev.md +69 -0
- package/_bmad/bmm/agents/sm.md +70 -0
- package/_bmad/bmm/agents/tea.md +70 -0
- package/_bmad/bmm/agents/tech-writer/tech-writer.md +70 -0
- package/_bmad/bmm/agents/ux-designer.md +57 -0
- package/_bmad/bmm/config.yaml +16 -0
- package/_bmad/bmm/data/project-context-template.md +26 -0
- package/_bmad/bmm/module-help.csv +32 -0
- package/_bmad/bmm/teams/default-party.csv +21 -0
- package/_bmad/bmm/teams/team-fullstack.yaml +12 -0
- package/_bmad/bmm/testarch/knowledge/adr-quality-readiness-checklist.md +350 -0
- package/_bmad/bmm/testarch/knowledge/api-request.md +442 -0
- package/_bmad/bmm/testarch/knowledge/api-testing-patterns.md +843 -0
- package/_bmad/bmm/testarch/knowledge/auth-session.md +552 -0
- package/_bmad/bmm/testarch/knowledge/burn-in.md +273 -0
- package/_bmad/bmm/testarch/knowledge/ci-burn-in.md +675 -0
- package/_bmad/bmm/testarch/knowledge/component-tdd.md +486 -0
- package/_bmad/bmm/testarch/knowledge/contract-testing.md +957 -0
- package/_bmad/bmm/testarch/knowledge/data-factories.md +500 -0
- package/_bmad/bmm/testarch/knowledge/email-auth.md +721 -0
- package/_bmad/bmm/testarch/knowledge/error-handling.md +725 -0
- package/_bmad/bmm/testarch/knowledge/feature-flags.md +750 -0
- package/_bmad/bmm/testarch/knowledge/file-utils.md +463 -0
- package/_bmad/bmm/testarch/knowledge/fixture-architecture.md +401 -0
- package/_bmad/bmm/testarch/knowledge/fixtures-composition.md +382 -0
- package/_bmad/bmm/testarch/knowledge/intercept-network-call.md +430 -0
- package/_bmad/bmm/testarch/knowledge/log.md +429 -0
- package/_bmad/bmm/testarch/knowledge/network-error-monitor.md +405 -0
- package/_bmad/bmm/testarch/knowledge/network-first.md +486 -0
- package/_bmad/bmm/testarch/knowledge/network-recorder.md +527 -0
- package/_bmad/bmm/testarch/knowledge/nfr-criteria.md +670 -0
- package/_bmad/bmm/testarch/knowledge/overview.md +286 -0
- package/_bmad/bmm/testarch/knowledge/playwright-config.md +730 -0
- package/_bmad/bmm/testarch/knowledge/probability-impact.md +601 -0
- package/_bmad/bmm/testarch/knowledge/recurse.md +421 -0
- package/_bmad/bmm/testarch/knowledge/risk-governance.md +615 -0
- package/_bmad/bmm/testarch/knowledge/selective-testing.md +732 -0
- package/_bmad/bmm/testarch/knowledge/selector-resilience.md +527 -0
- package/_bmad/bmm/testarch/knowledge/test-healing-patterns.md +644 -0
- package/_bmad/bmm/testarch/knowledge/test-levels-framework.md +473 -0
- package/_bmad/bmm/testarch/knowledge/test-priorities-matrix.md +373 -0
- package/_bmad/bmm/testarch/knowledge/test-quality.md +664 -0
- package/_bmad/bmm/testarch/knowledge/timing-debugging.md +372 -0
- package/_bmad/bmm/testarch/knowledge/visual-debugging.md +524 -0
- package/_bmad/bmm/testarch/tea-index.csv +35 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/product-brief.template.md +10 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01-init.md +177 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-01b-continue.md +161 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-02-vision.md +199 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-03-users.md +202 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-04-metrics.md +205 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-05-scope.md +219 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/steps/step-06-complete.md +162 -0
- package/_bmad/bmm/workflows/1-analysis/create-product-brief/workflow.md +58 -0
- package/_bmad/bmm/workflows/1-analysis/research/domain-steps/step-01-init.md +137 -0
- package/_bmad/bmm/workflows/1-analysis/research/domain-steps/step-02-domain-analysis.md +229 -0
- package/_bmad/bmm/workflows/1-analysis/research/domain-steps/step-03-competitive-landscape.md +238 -0
- package/_bmad/bmm/workflows/1-analysis/research/domain-steps/step-04-regulatory-focus.md +206 -0
- package/_bmad/bmm/workflows/1-analysis/research/domain-steps/step-05-technical-trends.md +234 -0
- package/_bmad/bmm/workflows/1-analysis/research/domain-steps/step-06-research-synthesis.md +443 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-01-init.md +182 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-behavior.md +237 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-02-customer-insights.md +200 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-03-customer-pain-points.md +249 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-04-customer-decisions.md +259 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-05-competitive-analysis.md +177 -0
- package/_bmad/bmm/workflows/1-analysis/research/market-steps/step-06-research-completion.md +475 -0
- package/_bmad/bmm/workflows/1-analysis/research/research.template.md +29 -0
- package/_bmad/bmm/workflows/1-analysis/research/technical-steps/step-01-init.md +137 -0
- package/_bmad/bmm/workflows/1-analysis/research/technical-steps/step-02-technical-overview.md +239 -0
- package/_bmad/bmm/workflows/1-analysis/research/technical-steps/step-03-integration-patterns.md +248 -0
- package/_bmad/bmm/workflows/1-analysis/research/technical-steps/step-04-architectural-patterns.md +202 -0
- package/_bmad/bmm/workflows/1-analysis/research/technical-steps/step-05-implementation-research.md +239 -0
- package/_bmad/bmm/workflows/1-analysis/research/technical-steps/step-06-research-synthesis.md +486 -0
- package/_bmad/bmm/workflows/1-analysis/research/workflow.md +173 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/domain-complexity.csv +13 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/prd-purpose.md +197 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/data/project-types.csv +11 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01-init.md +191 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-01b-continue.md +153 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-02-discovery.md +224 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-03-success.md +226 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-04-journeys.md +213 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-05-domain.md +207 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-06-innovation.md +226 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-07-project-type.md +237 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-08-scoping.md +228 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-09-functional.md +231 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-10-nonfunctional.md +242 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-11-polish.md +217 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-c/step-12-complete.md +124 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01-discovery.md +247 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-01b-legacy-conversion.md +208 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-02-review.md +249 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-03-edit.md +253 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-e/step-e-04-complete.md +168 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-01-discovery.md +218 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02-format-detection.md +191 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-02b-parity-check.md +209 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-03-density-validation.md +174 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-04-brief-coverage-validation.md +214 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-05-measurability-validation.md +228 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-06-traceability-validation.md +217 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-07-implementation-leakage-validation.md +205 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-08-domain-compliance-validation.md +243 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-09-project-type-validation.md +263 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-10-smart-validation.md +209 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-11-holistic-quality-validation.md +264 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-12-completeness-validation.md +242 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/steps-v/step-v-13-report-complete.md +231 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/templates/prd-template.md +10 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/validation-report-prd-workflow.md +433 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-prd/workflow.md +150 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01-init.md +135 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-01b-continue.md +127 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-02-discovery.md +190 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-03-core-experience.md +216 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-04-emotional-response.md +219 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-05-inspiration.md +234 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-06-design-system.md +252 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-07-defining-experience.md +254 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-08-visual-foundation.md +224 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-09-design-directions.md +224 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-10-user-journeys.md +241 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-11-component-strategy.md +248 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-12-ux-patterns.md +237 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-13-responsive-accessibility.md +264 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/steps/step-14-complete.md +171 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/ux-design-template.md +13 -0
- package/_bmad/bmm/workflows/2-plan-workflows/create-ux-design/workflow.md +43 -0
- package/_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-01-document-discovery.md +190 -0
- package/_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-02-prd-analysis.md +178 -0
- package/_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-03-epic-coverage-validation.md +179 -0
- package/_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-04-ux-alignment.md +139 -0
- package/_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-05-epic-quality-review.md +252 -0
- package/_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/steps/step-06-final-assessment.md +135 -0
- package/_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/templates/readiness-report-template.md +4 -0
- package/_bmad/bmm/workflows/3-solutioning/check-implementation-readiness/workflow.md +55 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/architecture-decision-template.md +12 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/data/domain-complexity.csv +11 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/data/project-types.csv +7 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01-init.md +153 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-01b-continue.md +164 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-02-context.md +224 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-03-starter.md +331 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-04-decisions.md +318 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-05-patterns.md +359 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-06-structure.md +379 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-07-validation.md +359 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/steps/step-08-complete.md +76 -0
- package/_bmad/bmm/workflows/3-solutioning/create-architecture/workflow.md +50 -0
- package/_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-01-validate-prerequisites.md +259 -0
- package/_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-02-design-epics.md +233 -0
- package/_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-03-create-stories.md +272 -0
- package/_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/steps/step-04-final-validation.md +149 -0
- package/_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/templates/epics-template.md +57 -0
- package/_bmad/bmm/workflows/3-solutioning/create-epics-and-stories/workflow.md +59 -0
- package/_bmad/bmm/workflows/4-implementation/code-review/checklist.md +23 -0
- package/_bmad/bmm/workflows/4-implementation/code-review/instructions.xml +227 -0
- package/_bmad/bmm/workflows/4-implementation/code-review/workflow.yaml +50 -0
- package/_bmad/bmm/workflows/4-implementation/correct-course/checklist.md +288 -0
- package/_bmad/bmm/workflows/4-implementation/correct-course/instructions.md +206 -0
- package/_bmad/bmm/workflows/4-implementation/correct-course/workflow.yaml +58 -0
- package/_bmad/bmm/workflows/4-implementation/create-story/checklist.md +358 -0
- package/_bmad/bmm/workflows/4-implementation/create-story/instructions.xml +345 -0
- package/_bmad/bmm/workflows/4-implementation/create-story/template.md +49 -0
- package/_bmad/bmm/workflows/4-implementation/create-story/workflow.yaml +59 -0
- package/_bmad/bmm/workflows/4-implementation/dev-story/checklist.md +80 -0
- package/_bmad/bmm/workflows/4-implementation/dev-story/instructions.xml +410 -0
- package/_bmad/bmm/workflows/4-implementation/dev-story/workflow.yaml +25 -0
- package/_bmad/bmm/workflows/4-implementation/retrospective/instructions.md +1443 -0
- package/_bmad/bmm/workflows/4-implementation/retrospective/workflow.yaml +57 -0
- package/_bmad/bmm/workflows/4-implementation/sprint-planning/checklist.md +33 -0
- package/_bmad/bmm/workflows/4-implementation/sprint-planning/instructions.md +225 -0
- package/_bmad/bmm/workflows/4-implementation/sprint-planning/sprint-status-template.yaml +55 -0
- package/_bmad/bmm/workflows/4-implementation/sprint-planning/workflow.yaml +52 -0
- package/_bmad/bmm/workflows/4-implementation/sprint-status/instructions.md +229 -0
- package/_bmad/bmm/workflows/4-implementation/sprint-status/workflow.yaml +35 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-01-mode-detection.md +176 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-02-context-gathering.md +120 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-03-execute.md +113 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-04-self-check.md +113 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-05-adversarial-review.md +106 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/steps/step-06-resolve-findings.md +149 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-dev/workflow.md +50 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-01-understand.md +192 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-02-investigate.md +145 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-03-generate.md +128 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-spec/steps/step-04-review.md +201 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-spec/tech-spec-template.md +74 -0
- package/_bmad/bmm/workflows/bmad-quick-flow/quick-spec/workflow.md +79 -0
- package/_bmad/bmm/workflows/document-project/checklist.md +245 -0
- package/_bmad/bmm/workflows/document-project/documentation-requirements.csv +12 -0
- package/_bmad/bmm/workflows/document-project/instructions.md +221 -0
- package/_bmad/bmm/workflows/document-project/templates/deep-dive-template.md +345 -0
- package/_bmad/bmm/workflows/document-project/templates/index-template.md +169 -0
- package/_bmad/bmm/workflows/document-project/templates/project-overview-template.md +103 -0
- package/_bmad/bmm/workflows/document-project/templates/project-scan-report-schema.json +160 -0
- package/_bmad/bmm/workflows/document-project/templates/source-tree-template.md +135 -0
- package/_bmad/bmm/workflows/document-project/workflow.yaml +28 -0
- package/_bmad/bmm/workflows/document-project/workflows/deep-dive-instructions.md +298 -0
- package/_bmad/bmm/workflows/document-project/workflows/deep-dive.yaml +31 -0
- package/_bmad/bmm/workflows/document-project/workflows/full-scan-instructions.md +1106 -0
- package/_bmad/bmm/workflows/document-project/workflows/full-scan.yaml +31 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-library.json +90 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/_shared/excalidraw-templates.yaml +127 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/checklist.md +39 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/instructions.md +130 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-dataflow/workflow.yaml +26 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-diagram/checklist.md +43 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-diagram/instructions.md +141 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-diagram/workflow.yaml +26 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/checklist.md +49 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/instructions.md +241 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-flowchart/workflow.yaml +26 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/checklist.md +38 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/instructions.md +133 -0
- package/_bmad/bmm/workflows/excalidraw-diagrams/create-wireframe/workflow.yaml +26 -0
- package/_bmad/bmm/workflows/testarch/atdd/atdd-checklist-template.md +363 -0
- package/_bmad/bmm/workflows/testarch/atdd/checklist.md +374 -0
- package/_bmad/bmm/workflows/testarch/atdd/instructions.md +806 -0
- package/_bmad/bmm/workflows/testarch/atdd/workflow.yaml +45 -0
- package/_bmad/bmm/workflows/testarch/automate/checklist.md +582 -0
- package/_bmad/bmm/workflows/testarch/automate/instructions.md +1324 -0
- package/_bmad/bmm/workflows/testarch/automate/workflow.yaml +52 -0
- package/_bmad/bmm/workflows/testarch/ci/checklist.md +247 -0
- package/_bmad/bmm/workflows/testarch/ci/github-actions-template.yaml +198 -0
- package/_bmad/bmm/workflows/testarch/ci/gitlab-ci-template.yaml +149 -0
- package/_bmad/bmm/workflows/testarch/ci/instructions.md +536 -0
- package/_bmad/bmm/workflows/testarch/ci/workflow.yaml +45 -0
- package/_bmad/bmm/workflows/testarch/framework/checklist.md +320 -0
- package/_bmad/bmm/workflows/testarch/framework/instructions.md +481 -0
- package/_bmad/bmm/workflows/testarch/framework/workflow.yaml +47 -0
- package/_bmad/bmm/workflows/testarch/nfr-assess/checklist.md +407 -0
- package/_bmad/bmm/workflows/testarch/nfr-assess/instructions.md +726 -0
- package/_bmad/bmm/workflows/testarch/nfr-assess/nfr-report-template.md +461 -0
- package/_bmad/bmm/workflows/testarch/nfr-assess/workflow.yaml +47 -0
- package/_bmad/bmm/workflows/testarch/test-design/checklist.md +407 -0
- package/_bmad/bmm/workflows/testarch/test-design/instructions.md +1158 -0
- package/_bmad/bmm/workflows/testarch/test-design/test-design-architecture-template.md +213 -0
- package/_bmad/bmm/workflows/testarch/test-design/test-design-qa-template.md +286 -0
- package/_bmad/bmm/workflows/testarch/test-design/test-design-template.md +294 -0
- package/_bmad/bmm/workflows/testarch/test-design/workflow.yaml +69 -0
- package/_bmad/bmm/workflows/testarch/test-review/checklist.md +472 -0
- package/_bmad/bmm/workflows/testarch/test-review/instructions.md +628 -0
- package/_bmad/bmm/workflows/testarch/test-review/test-review-template.md +390 -0
- package/_bmad/bmm/workflows/testarch/test-review/workflow.yaml +46 -0
- package/_bmad/bmm/workflows/testarch/trace/checklist.md +642 -0
- package/_bmad/bmm/workflows/testarch/trace/instructions.md +1030 -0
- package/_bmad/bmm/workflows/testarch/trace/trace-template.md +675 -0
- package/_bmad/bmm/workflows/testarch/trace/workflow.yaml +55 -0
- package/_bmad/core/agents/bmad-master.md +56 -0
- package/_bmad/core/config.yaml +9 -0
- package/_bmad/core/module-help.csv +9 -0
- package/_bmad/core/resources/excalidraw/README.md +160 -0
- package/_bmad/core/resources/excalidraw/excalidraw-helpers.md +127 -0
- package/_bmad/core/resources/excalidraw/library-loader.md +50 -0
- package/_bmad/core/resources/excalidraw/validate-json-instructions.md +79 -0
- package/_bmad/core/tasks/editorial-review-prose.xml +100 -0
- package/_bmad/core/tasks/editorial-review-structure.xml +209 -0
- package/_bmad/core/tasks/help.md +62 -0
- package/_bmad/core/tasks/index-docs.xml +65 -0
- package/_bmad/core/tasks/review-adversarial-general.xml +48 -0
- package/_bmad/core/tasks/shard-doc.xml +109 -0
- package/_bmad/core/tasks/workflow.xml +235 -0
- package/_bmad/core/workflows/advanced-elicitation/methods.csv +51 -0
- package/_bmad/core/workflows/advanced-elicitation/workflow.xml +117 -0
- package/_bmad/core/workflows/brainstorming/brain-methods.csv +62 -0
- package/_bmad/core/workflows/brainstorming/steps/step-01-session-setup.md +197 -0
- package/_bmad/core/workflows/brainstorming/steps/step-01b-continue.md +122 -0
- package/_bmad/core/workflows/brainstorming/steps/step-02a-user-selected.md +225 -0
- package/_bmad/core/workflows/brainstorming/steps/step-02b-ai-recommended.md +237 -0
- package/_bmad/core/workflows/brainstorming/steps/step-02c-random-selection.md +209 -0
- package/_bmad/core/workflows/brainstorming/steps/step-02d-progressive-flow.md +264 -0
- package/_bmad/core/workflows/brainstorming/steps/step-03-technique-execution.md +399 -0
- package/_bmad/core/workflows/brainstorming/steps/step-04-idea-organization.md +303 -0
- package/_bmad/core/workflows/brainstorming/template.md +15 -0
- package/_bmad/core/workflows/brainstorming/workflow.md +58 -0
- package/_bmad/core/workflows/party-mode/steps/step-01-agent-loading.md +138 -0
- package/_bmad/core/workflows/party-mode/steps/step-02-discussion-orchestration.md +187 -0
- package/_bmad/core/workflows/party-mode/steps/step-03-graceful-exit.md +157 -0
- package/_bmad/core/workflows/party-mode/workflow.md +194 -0
- package/dist/api/client.d.ts +16 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +91 -5
- package/dist/api/client.js.map +1 -1
- package/dist/api/projects.d.ts +23 -2
- package/dist/api/projects.d.ts.map +1 -1
- package/dist/api/projects.js +32 -0
- package/dist/api/projects.js.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/projects/delete-attachment-from-task.d.ts.map +1 -0
- package/dist/tools/projects/delete-attachment-from-task.js.map +1 -0
- package/dist/tools/projects/delete-attachment.d.ts +55 -0
- package/dist/tools/projects/delete-attachment.d.ts.map +1 -0
- package/dist/tools/projects/delete-attachment.js +115 -0
- package/dist/tools/projects/delete-attachment.js.map +1 -0
- package/dist/tools/projects/download-attachment.d.ts +55 -0
- package/dist/tools/projects/download-attachment.d.ts.map +1 -0
- package/dist/tools/projects/download-attachment.js +153 -0
- package/dist/tools/projects/download-attachment.js.map +1 -0
- package/dist/tools/projects/get-attachment-list.d.ts +48 -0
- package/dist/tools/projects/get-attachment-list.d.ts.map +1 -0
- package/dist/tools/projects/get-attachment-list.js +118 -0
- package/dist/tools/projects/get-attachment-list.js.map +1 -0
- package/dist/tools/projects/get-attachment-metadata.d.ts +55 -0
- package/dist/tools/projects/get-attachment-metadata.d.ts.map +1 -0
- package/dist/tools/projects/get-attachment-metadata.js +120 -0
- package/dist/tools/projects/get-attachment-metadata.js.map +1 -0
- package/dist/tools/projects/register-attachment-to-task.d.ts.map +1 -0
- package/dist/tools/projects/register-attachment-to-task.js.map +1 -0
- package/dist/tools/projects/update-task.d.ts +4 -4
- package/dist/tools/projects/update-task.js +12 -12
- package/dist/tools/projects/update-task.js.map +1 -1
- package/dist/tools/projects/upload-attachment.d.ts +69 -0
- package/dist/tools/projects/upload-attachment.d.ts.map +1 -0
- package/dist/tools/projects/upload-attachment.js +109 -0
- package/dist/tools/projects/upload-attachment.js.map +1 -0
- package/dist/types/dooray-api.d.ts +15 -0
- package/dist/types/dooray-api.d.ts.map +1 -1
- package/docs/architecture.md +227 -0
- package/docs/development-guide.md +336 -0
- package/docs/index.md +115 -0
- package/docs/project-overview.md +105 -0
- package/docs/project-scan-report.json +120 -0
- package/docs/source-tree-analysis.md +240 -0
- package/package.json +1 -1
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
# Recurse (Polling) Utility
|
|
2
|
+
|
|
3
|
+
## Principle
|
|
4
|
+
|
|
5
|
+
Use Cypress-style polling with Playwright's `expect.poll` to wait for asynchronous conditions. Provides configurable timeout, interval, logging, and post-polling callbacks with enhanced error categorization. **Ideal for backend testing**: polling API endpoints for job completion, database eventual consistency, message queue processing, and cache propagation.
|
|
6
|
+
|
|
7
|
+
## Rationale
|
|
8
|
+
|
|
9
|
+
Testing async operations (background jobs, eventual consistency, webhook processing) requires polling:
|
|
10
|
+
|
|
11
|
+
- Vanilla `expect.poll` is verbose
|
|
12
|
+
- No built-in logging for debugging
|
|
13
|
+
- Generic timeout errors
|
|
14
|
+
- No post-poll hooks
|
|
15
|
+
|
|
16
|
+
The `recurse` utility provides:
|
|
17
|
+
|
|
18
|
+
- **Clean syntax**: Inspired by cypress-recurse
|
|
19
|
+
- **Enhanced errors**: Timeout vs command failure vs predicate errors
|
|
20
|
+
- **Built-in logging**: Track polling progress
|
|
21
|
+
- **Post-poll callbacks**: Process results after success
|
|
22
|
+
- **Type-safe**: Full TypeScript generic support
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { test } from '@seontechnologies/playwright-utils/recurse/fixtures';
|
|
28
|
+
|
|
29
|
+
test('wait for job completion', async ({ recurse, apiRequest }) => {
|
|
30
|
+
const { body } = await apiRequest({
|
|
31
|
+
method: 'POST',
|
|
32
|
+
path: '/api/jobs',
|
|
33
|
+
body: { type: 'export' },
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Poll until job completes
|
|
37
|
+
const result = await recurse(
|
|
38
|
+
() => apiRequest({ method: 'GET', path: `/api/jobs/${body.id}` }),
|
|
39
|
+
(response) => response.body.status === 'completed',
|
|
40
|
+
{ timeout: 60000 }
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
expect(result.body.downloadUrl).toBeDefined();
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Pattern Examples
|
|
48
|
+
|
|
49
|
+
### Example 1: Basic Polling
|
|
50
|
+
|
|
51
|
+
**Context**: Wait for async operation to complete with custom timeout and interval.
|
|
52
|
+
|
|
53
|
+
**Implementation**:
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { test } from '@seontechnologies/playwright-utils/recurse/fixtures';
|
|
57
|
+
|
|
58
|
+
test('should wait for job completion', async ({ recurse, apiRequest }) => {
|
|
59
|
+
// Start job
|
|
60
|
+
const { body } = await apiRequest({
|
|
61
|
+
method: 'POST',
|
|
62
|
+
path: '/api/jobs',
|
|
63
|
+
body: { type: 'export' },
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// Poll until ready
|
|
67
|
+
const result = await recurse(
|
|
68
|
+
() => apiRequest({ method: 'GET', path: `/api/jobs/${body.id}` }),
|
|
69
|
+
(response) => response.body.status === 'completed',
|
|
70
|
+
{
|
|
71
|
+
timeout: 60000, // 60 seconds max
|
|
72
|
+
interval: 2000, // Check every 2 seconds
|
|
73
|
+
log: 'Waiting for export job to complete',
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
expect(result.body.downloadUrl).toBeDefined();
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Key Points**:
|
|
82
|
+
|
|
83
|
+
- First arg: command function (what to execute)
|
|
84
|
+
- Second arg: predicate function (when to stop)
|
|
85
|
+
- Options: timeout, interval, log message
|
|
86
|
+
- Returns the value when predicate returns true
|
|
87
|
+
|
|
88
|
+
### Example 2: Working with Assertions
|
|
89
|
+
|
|
90
|
+
**Context**: Use assertions directly in predicate for more expressive tests.
|
|
91
|
+
|
|
92
|
+
**Implementation**:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
test('should poll with assertions', async ({ recurse, apiRequest }) => {
|
|
96
|
+
await apiRequest({
|
|
97
|
+
method: 'POST',
|
|
98
|
+
path: '/api/events',
|
|
99
|
+
body: { type: 'user-created', userId: '123' },
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Poll with assertions in predicate - no return true needed!
|
|
103
|
+
await recurse(
|
|
104
|
+
async () => {
|
|
105
|
+
const { body } = await apiRequest({ method: 'GET', path: '/api/events/123' });
|
|
106
|
+
return body;
|
|
107
|
+
},
|
|
108
|
+
(event) => {
|
|
109
|
+
// If all assertions pass, predicate succeeds
|
|
110
|
+
expect(event.processed).toBe(true);
|
|
111
|
+
expect(event.timestamp).toBeDefined();
|
|
112
|
+
// No need to return true - just let assertions pass
|
|
113
|
+
},
|
|
114
|
+
{ timeout: 30000 }
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**Why no `return true` needed?**
|
|
120
|
+
|
|
121
|
+
The predicate checks for "truthiness" of the return value. But there's a catch - in JavaScript, an empty `return` (or no return) returns `undefined`, which is falsy!
|
|
122
|
+
|
|
123
|
+
The utility handles this by checking if:
|
|
124
|
+
|
|
125
|
+
1. The predicate didn't throw (assertions passed)
|
|
126
|
+
2. The return value was either `undefined` (implicit return) or truthy
|
|
127
|
+
|
|
128
|
+
So you can:
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
// Option 1: Use assertions only (recommended)
|
|
132
|
+
(event) => {
|
|
133
|
+
expect(event.processed).toBe(true);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// Option 2: Return boolean (also works)
|
|
137
|
+
(event) => event.processed === true;
|
|
138
|
+
|
|
139
|
+
// Option 3: Mixed (assertions + explicit return)
|
|
140
|
+
(event) => {
|
|
141
|
+
expect(event.processed).toBe(true);
|
|
142
|
+
return true;
|
|
143
|
+
};
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Example 3: Error Handling
|
|
147
|
+
|
|
148
|
+
**Context**: Understanding the different error types.
|
|
149
|
+
|
|
150
|
+
**Error Types:**
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// RecurseTimeoutError - Predicate never returned true within timeout
|
|
154
|
+
// Contains last command value and predicate error
|
|
155
|
+
try {
|
|
156
|
+
await recurse(/* ... */);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
if (error instanceof RecurseTimeoutError) {
|
|
159
|
+
console.log('Timed out. Last value:', error.lastCommandValue);
|
|
160
|
+
console.log('Last predicate error:', error.lastPredicateError);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// RecurseCommandError - Command function threw an error
|
|
165
|
+
// The command itself failed (e.g., network error, API error)
|
|
166
|
+
|
|
167
|
+
// RecursePredicateError - Predicate function threw (not from assertions failing)
|
|
168
|
+
// Logic error in your predicate code
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**Custom Error Messages:**
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
test('custom error on timeout', async ({ recurse, apiRequest }) => {
|
|
175
|
+
try {
|
|
176
|
+
await recurse(
|
|
177
|
+
() => apiRequest({ method: 'GET', path: '/api/status' }),
|
|
178
|
+
(res) => res.body.ready === true,
|
|
179
|
+
{
|
|
180
|
+
timeout: 10000,
|
|
181
|
+
error: 'System failed to become ready within 10 seconds - check background workers',
|
|
182
|
+
}
|
|
183
|
+
);
|
|
184
|
+
} catch (error) {
|
|
185
|
+
// Error message includes custom context
|
|
186
|
+
expect(error.message).toContain('check background workers');
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Example 4: Post-Polling Callback
|
|
193
|
+
|
|
194
|
+
**Context**: Process or log results after successful polling.
|
|
195
|
+
|
|
196
|
+
**Implementation**:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
test('post-poll processing', async ({ recurse, apiRequest }) => {
|
|
200
|
+
const finalResult = await recurse(
|
|
201
|
+
() => apiRequest({ method: 'GET', path: '/api/batch-job/123' }),
|
|
202
|
+
(res) => res.body.status === 'completed',
|
|
203
|
+
{
|
|
204
|
+
timeout: 60000,
|
|
205
|
+
post: (result) => {
|
|
206
|
+
// Runs after successful polling
|
|
207
|
+
console.log(`Job completed in ${result.body.duration}ms`);
|
|
208
|
+
console.log(`Processed ${result.body.itemsProcessed} items`);
|
|
209
|
+
return result.body;
|
|
210
|
+
},
|
|
211
|
+
}
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
expect(finalResult.itemsProcessed).toBeGreaterThan(0);
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Key Points**:
|
|
219
|
+
|
|
220
|
+
- `post` callback runs after predicate succeeds
|
|
221
|
+
- Receives the final result
|
|
222
|
+
- Can transform or log results
|
|
223
|
+
- Return value becomes final `recurse` result
|
|
224
|
+
|
|
225
|
+
### Example 5: UI Testing Scenarios
|
|
226
|
+
|
|
227
|
+
**Context**: Wait for UI elements to reach a specific state through polling.
|
|
228
|
+
|
|
229
|
+
**Implementation**:
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
test('table data loads', async ({ page, recurse }) => {
|
|
233
|
+
await page.goto('/reports');
|
|
234
|
+
|
|
235
|
+
// Poll for table rows to appear
|
|
236
|
+
await recurse(
|
|
237
|
+
async () => page.locator('table tbody tr').count(),
|
|
238
|
+
(count) => count >= 10, // Wait for at least 10 rows
|
|
239
|
+
{
|
|
240
|
+
timeout: 15000,
|
|
241
|
+
interval: 500,
|
|
242
|
+
log: 'Waiting for table data to load',
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// Now safe to interact with table
|
|
247
|
+
await page.locator('table tbody tr').first().click();
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Example 6: Event-Based Systems (Kafka/Message Queues)
|
|
252
|
+
|
|
253
|
+
**Context**: Testing eventual consistency with message queue processing.
|
|
254
|
+
|
|
255
|
+
**Implementation**:
|
|
256
|
+
|
|
257
|
+
```typescript
|
|
258
|
+
test('kafka event processed', async ({ recurse, apiRequest }) => {
|
|
259
|
+
// Trigger action that publishes Kafka event
|
|
260
|
+
await apiRequest({
|
|
261
|
+
method: 'POST',
|
|
262
|
+
path: '/api/orders',
|
|
263
|
+
body: { productId: 'ABC123', quantity: 2 },
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
// Poll for downstream effect of Kafka consumer processing
|
|
267
|
+
const inventoryResult = await recurse(
|
|
268
|
+
() => apiRequest({ method: 'GET', path: '/api/inventory/ABC123' }),
|
|
269
|
+
(res) => {
|
|
270
|
+
// Assumes test fixture seeds inventory at 100; in production tests,
|
|
271
|
+
// fetch baseline first and assert: expect(res.body.available).toBe(baseline - 2)
|
|
272
|
+
expect(res.body.available).toBeLessThanOrEqual(98);
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
timeout: 30000, // Kafka processing may take time
|
|
276
|
+
interval: 1000,
|
|
277
|
+
log: 'Waiting for Kafka event to be processed',
|
|
278
|
+
}
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
expect(inventoryResult.body.lastOrderId).toBeDefined();
|
|
282
|
+
});
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### Example 7: Integration with API Request (Common Pattern)
|
|
286
|
+
|
|
287
|
+
**Context**: Most common use case - polling API endpoints for state changes.
|
|
288
|
+
|
|
289
|
+
**Implementation**:
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import { test } from '@seontechnologies/playwright-utils/fixtures';
|
|
293
|
+
|
|
294
|
+
test('end-to-end polling', async ({ apiRequest, recurse }) => {
|
|
295
|
+
// Trigger async operation
|
|
296
|
+
const { body: createResp } = await apiRequest({
|
|
297
|
+
method: 'POST',
|
|
298
|
+
path: '/api/data-import',
|
|
299
|
+
body: { source: 's3://bucket/data.csv' },
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// Poll until import completes
|
|
303
|
+
const importResult = await recurse(
|
|
304
|
+
() => apiRequest({ method: 'GET', path: `/api/data-import/${createResp.importId}` }),
|
|
305
|
+
(response) => {
|
|
306
|
+
const { status, rowsImported } = response.body;
|
|
307
|
+
return status === 'completed' && rowsImported > 0;
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
timeout: 120000, // 2 minutes for large imports
|
|
311
|
+
interval: 5000, // Check every 5 seconds
|
|
312
|
+
log: `Polling import ${createResp.importId}`,
|
|
313
|
+
}
|
|
314
|
+
);
|
|
315
|
+
|
|
316
|
+
expect(importResult.body.rowsImported).toBeGreaterThan(1000);
|
|
317
|
+
expect(importResult.body.errors).toHaveLength(0);
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**Key Points**:
|
|
322
|
+
|
|
323
|
+
- Combine `apiRequest` + `recurse` for API polling
|
|
324
|
+
- Both from `@seontechnologies/playwright-utils/fixtures`
|
|
325
|
+
- Complex predicates with multiple conditions
|
|
326
|
+
- Logging shows polling progress in test reports
|
|
327
|
+
|
|
328
|
+
## API Reference
|
|
329
|
+
|
|
330
|
+
### RecurseOptions
|
|
331
|
+
|
|
332
|
+
| Option | Type | Default | Description |
|
|
333
|
+
| ---------- | ------------------ | ----------- | ------------------------------------ |
|
|
334
|
+
| `timeout` | `number` | `30000` | Maximum time to wait (ms) |
|
|
335
|
+
| `interval` | `number` | `1000` | Time between polls (ms) |
|
|
336
|
+
| `log` | `string` | `undefined` | Message logged on each poll |
|
|
337
|
+
| `error` | `string` | `undefined` | Custom error message for timeout |
|
|
338
|
+
| `post` | `(result: T) => R` | `undefined` | Callback after successful poll |
|
|
339
|
+
| `delay` | `number` | `0` | Initial delay before first poll (ms) |
|
|
340
|
+
|
|
341
|
+
### Error Types
|
|
342
|
+
|
|
343
|
+
| Error Type | When Thrown | Properties |
|
|
344
|
+
| ----------------------- | --------------------------------------- | ---------------------------------------- |
|
|
345
|
+
| `RecurseTimeoutError` | Predicate never passed within timeout | `lastCommandValue`, `lastPredicateError` |
|
|
346
|
+
| `RecurseCommandError` | Command function threw an error | `cause` (original error) |
|
|
347
|
+
| `RecursePredicateError` | Predicate threw (not assertion failure) | `cause` (original error) |
|
|
348
|
+
|
|
349
|
+
## Comparison with Vanilla Playwright
|
|
350
|
+
|
|
351
|
+
| Vanilla Playwright | recurse Utility |
|
|
352
|
+
| ----------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
353
|
+
| `await expect.poll(() => { ... }, { timeout: 30000 }).toBe(true)` | `await recurse(() => { ... }, (val) => val === true, { timeout: 30000 })` |
|
|
354
|
+
| No logging | Built-in log option |
|
|
355
|
+
| Generic timeout errors | Categorized errors (timeout/command/predicate) |
|
|
356
|
+
| No post-poll hooks | `post` callback support |
|
|
357
|
+
|
|
358
|
+
## When to Use
|
|
359
|
+
|
|
360
|
+
**Use recurse for:**
|
|
361
|
+
|
|
362
|
+
- Background job completion
|
|
363
|
+
- Webhook/event processing
|
|
364
|
+
- Database eventual consistency
|
|
365
|
+
- Cache propagation
|
|
366
|
+
- State machine transitions
|
|
367
|
+
|
|
368
|
+
**Stick with vanilla expect.poll for:**
|
|
369
|
+
|
|
370
|
+
- Simple UI element visibility (use `expect(locator).toBeVisible()`)
|
|
371
|
+
- Single-property checks
|
|
372
|
+
- Cases where logging isn't needed
|
|
373
|
+
|
|
374
|
+
## Related Fragments
|
|
375
|
+
|
|
376
|
+
- `api-testing-patterns.md` - Comprehensive pure API testing patterns
|
|
377
|
+
- `api-request.md` - Combine for API endpoint polling
|
|
378
|
+
- `overview.md` - Fixture composition patterns
|
|
379
|
+
- `fixtures-composition.md` - Using with mergeTests
|
|
380
|
+
- `contract-testing.md` - Contract testing with async verification
|
|
381
|
+
|
|
382
|
+
## Anti-Patterns
|
|
383
|
+
|
|
384
|
+
**DON'T use hard waits instead of polling:**
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
await page.click('#export');
|
|
388
|
+
await page.waitForTimeout(5000); // Arbitrary wait
|
|
389
|
+
expect(await page.textContent('#status')).toBe('Ready');
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**DO poll for actual condition:**
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
await page.click('#export');
|
|
396
|
+
await recurse(
|
|
397
|
+
() => page.textContent('#status'),
|
|
398
|
+
(status) => status === 'Ready',
|
|
399
|
+
{ timeout: 10000 }
|
|
400
|
+
);
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**DON'T poll too frequently:**
|
|
404
|
+
|
|
405
|
+
```typescript
|
|
406
|
+
await recurse(
|
|
407
|
+
() => apiRequest({ method: 'GET', path: '/status' }),
|
|
408
|
+
(res) => res.body.ready,
|
|
409
|
+
{ interval: 100 } // Hammers API every 100ms!
|
|
410
|
+
);
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
**DO use reasonable interval for API calls:**
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
await recurse(
|
|
417
|
+
() => apiRequest({ method: 'GET', path: '/status' }),
|
|
418
|
+
(res) => res.body.ready,
|
|
419
|
+
{ interval: 2000 } // Check every 2 seconds (reasonable)
|
|
420
|
+
);
|
|
421
|
+
```
|