@nextsparkjs/theme-default 0.1.0-beta.17 → 0.1.0-beta.171
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/api/ai/chat/stream/route.ts +4 -1
- package/api/ai/orchestrator/route.ts +10 -3
- package/api/ai/single-agent/route.ts +10 -3
- package/api/ai/usage/route.ts +4 -1
- package/blocks/benefits/component.tsx +4 -4
- package/blocks/cta-section/component.tsx +4 -4
- package/blocks/faq-accordion/component.tsx +2 -2
- package/blocks/features-grid/component.tsx +5 -5
- package/blocks/hero/component.tsx +2 -2
- package/blocks/hero/fields.ts +1 -1
- package/blocks/hero-with-form/component.tsx +7 -7
- package/blocks/hero-with-form/fields.ts +1 -1
- package/blocks/jumbotron/component.tsx +7 -7
- package/blocks/jumbotron/fields.ts +1 -1
- package/blocks/logo-cloud/component.tsx +6 -6
- package/blocks/logo-cloud/fields.ts +1 -1
- package/blocks/post-content/component.tsx +2 -2
- package/blocks/pricing-table/component.tsx +5 -5
- package/blocks/split-content/component.tsx +5 -5
- package/blocks/split-content/fields.ts +1 -1
- package/blocks/stats-counter/component.tsx +9 -9
- package/blocks/testimonials/component.tsx +4 -4
- package/blocks/testimonials/fields.ts +1 -1
- package/blocks/text-content/component.tsx +12 -10
- package/blocks/timeline/component.tsx +12 -12
- package/blocks/video-hero/component.tsx +7 -7
- package/blocks/video-hero/fields.ts +1 -1
- package/components/ai-chat/ChatPanel.tsx +7 -7
- package/components/ai-chat/Message.tsx +2 -2
- package/components/ai-chat/MessageInput.tsx +3 -3
- package/components/ai-chat/MessageList.tsx +3 -3
- package/components/ai-chat/TypingIndicator.tsx +2 -2
- package/config/app.config.ts +90 -62
- package/config/billing.config.ts +5 -10
- package/config/dashboard.config.ts +14 -0
- package/config/features.config.ts +10 -0
- package/config/permissions.config.ts +22 -23
- package/docs/{01-overview → public/01-overview}/01-introduction.md +5 -0
- package/docs/{01-overview → public/01-overview}/02-customization.md +5 -0
- package/docs/{02-features → public/02-features}/03-tasks-entity.md +5 -0
- package/docs/{03-ai → public/03-ai}/01-overview.md +5 -0
- package/docs/{03-ai → public/03-ai}/02-customization.md +5 -0
- package/docs/superadmin/01-setup/01-configuration.md +79 -0
- package/docs/superadmin/01-setup/02-deployment.md +82 -0
- package/docs/superadmin/02-management/01-users.md +83 -0
- package/docs/superadmin/03-integrations/01-langchain.md +139 -0
- package/emails/verify-email.ts +33 -0
- package/entities/customers/api/docs.md +107 -0
- package/entities/customers/api/presets.ts +80 -0
- package/entities/pages/api/docs.md +114 -0
- package/entities/pages/api/presets.ts +72 -0
- package/entities/posts/api/docs.md +120 -0
- package/entities/posts/api/presets.ts +74 -0
- package/entities/tasks/api/docs.md +126 -0
- package/entities/tasks/api/presets.ts +84 -0
- package/lib/selectors.ts +7 -4
- package/messages/de/admin.json +45 -0
- package/messages/en/admin.json +56 -0
- package/messages/en/navigation.json +2 -1
- package/messages/es/admin.json +56 -0
- package/messages/es/navigation.json +2 -1
- package/messages/fr/admin.json +45 -0
- package/messages/it/admin.json +45 -0
- package/messages/pt/admin.json +45 -0
- package/migrations/089_add_editor_team_role.sql +15 -23
- package/migrations/090_demo_users_teams.sql +11 -11
- package/migrations/091_greek_teams_billing.sql +15 -15
- package/migrations/093_pages_sample_data.sql +7 -7
- package/migrations/098_patterns_sample_data.sql +234 -0
- package/nextsparkjs-theme-default-0.1.0-beta.137.tgz +0 -0
- package/package.json +4 -3
- package/styles/globals.css +42 -0
- package/templates/(public)/page.tsx +1 -1
- package/tests/cypress/e2e/_utils/devtools/access.bdd.md +262 -0
- package/tests/cypress/e2e/_utils/devtools/access.cy.ts +171 -0
- package/tests/cypress/e2e/_utils/devtools/navigation.bdd.md +261 -0
- package/tests/cypress/e2e/_utils/devtools/navigation.cy.ts +157 -0
- package/tests/cypress/e2e/_utils/devtools/pages.bdd.md +303 -0
- package/tests/cypress/e2e/_utils/devtools/pages.cy.ts +184 -0
- package/tests/cypress/e2e/_utils/docs/README.md +215 -0
- package/tests/cypress/e2e/_utils/selectors/auth.bdd.md +354 -0
- package/tests/cypress/e2e/_utils/selectors/auth.cy.ts +310 -0
- package/tests/cypress/e2e/_utils/selectors/billing.bdd.md +276 -0
- package/tests/cypress/e2e/_utils/selectors/billing.cy.ts +182 -0
- package/tests/cypress/e2e/_utils/selectors/block-editor.bdd.md +615 -0
- package/tests/cypress/e2e/_utils/selectors/block-editor.cy.ts +783 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-container.cy.ts +52 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-mobile.bdd.md +205 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-mobile.cy.ts +137 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-navigation.bdd.md +147 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-navigation.cy.ts +114 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-sidebar.bdd.md +76 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-sidebar.cy.ts +68 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-topnav.bdd.md +326 -0
- package/tests/cypress/e2e/_utils/selectors/dashboard-topnav.cy.ts +177 -0
- package/tests/cypress/e2e/_utils/selectors/devtools.bdd.md +306 -0
- package/tests/cypress/e2e/_utils/selectors/devtools.cy.ts +273 -0
- package/tests/cypress/e2e/_utils/selectors/global-search.bdd.md +115 -0
- package/tests/cypress/e2e/_utils/selectors/global-search.cy.ts +93 -0
- package/tests/cypress/e2e/_utils/selectors/patterns.bdd.md +388 -0
- package/tests/cypress/e2e/_utils/selectors/patterns.cy.ts +559 -0
- package/tests/cypress/e2e/_utils/selectors/public.cy.ts +112 -0
- package/tests/cypress/e2e/_utils/selectors/settings-api-keys.bdd.md +266 -0
- package/tests/cypress/e2e/_utils/selectors/settings-api-keys.cy.ts +233 -0
- package/tests/cypress/e2e/_utils/selectors/settings-billing.bdd.md +78 -0
- package/tests/cypress/e2e/_utils/selectors/settings-billing.cy.ts +108 -0
- package/tests/cypress/e2e/_utils/selectors/settings-layout.bdd.md +129 -0
- package/tests/cypress/e2e/_utils/selectors/settings-layout.cy.ts +115 -0
- package/tests/cypress/e2e/_utils/selectors/settings-password.bdd.md +82 -0
- package/tests/cypress/e2e/_utils/selectors/settings-password.cy.ts +74 -0
- package/tests/cypress/e2e/_utils/selectors/settings-profile.bdd.md +77 -0
- package/tests/cypress/e2e/_utils/selectors/settings-profile.cy.ts +79 -0
- package/tests/cypress/e2e/_utils/selectors/settings-teams.bdd.md +130 -0
- package/tests/cypress/e2e/_utils/selectors/settings-teams.cy.ts +86 -0
- package/tests/cypress/e2e/_utils/selectors/superadmin.bdd.md +261 -0
- package/tests/cypress/e2e/_utils/selectors/superadmin.cy.ts +193 -0
- package/tests/cypress/e2e/_utils/selectors/tasks.bdd.md +593 -0
- package/tests/cypress/e2e/_utils/selectors/tasks.cy.ts +864 -0
- package/tests/cypress/e2e/_utils/selectors/taxonomies.cy.ts +126 -0
- package/tests/cypress/e2e/_utils/selectors/teams.bdd.md +278 -0
- package/tests/cypress/e2e/_utils/selectors/teams.cy.ts +195 -0
- package/tests/cypress/e2e/_utils/superadmin/all-teams.bdd.md +261 -0
- package/tests/cypress/e2e/_utils/superadmin/all-teams.cy.ts +177 -0
- package/tests/cypress/e2e/_utils/superadmin/all-users.bdd.md +406 -0
- package/tests/cypress/e2e/_utils/superadmin/all-users.cy.ts +294 -0
- package/tests/cypress/e2e/_utils/superadmin/dashboard.bdd.md +235 -0
- package/tests/cypress/e2e/_utils/superadmin/dashboard.cy.ts +149 -0
- package/tests/cypress/e2e/_utils/superadmin/subscriptions-overview.bdd.md +290 -0
- package/tests/cypress/e2e/_utils/superadmin/subscriptions-overview.cy.ts +194 -0
- package/tests/cypress/e2e/ai/ai-usage.cy.ts +209 -0
- package/tests/cypress/e2e/ai/chat-api.cy.ts +119 -0
- package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
- package/tests/cypress/e2e/api/_core/billing/BillingAPIController.js +319 -0
- package/tests/cypress/e2e/api/_core/billing/check-action.cy.ts +326 -0
- package/tests/cypress/e2e/api/_core/billing/checkout.cy.ts +358 -0
- package/tests/cypress/e2e/api/_core/billing/lifecycle.cy.ts +423 -0
- package/tests/cypress/e2e/api/_core/billing/plans/README.md +345 -0
- package/tests/cypress/e2e/api/_core/billing/plans/business.cy.ts +412 -0
- package/tests/cypress/e2e/api/_core/billing/plans/downgrade.cy.ts +510 -0
- package/tests/cypress/e2e/api/_core/billing/plans/fixtures/billing-plans.json +163 -0
- package/tests/cypress/e2e/api/_core/billing/plans/free.cy.ts +500 -0
- package/tests/cypress/e2e/api/_core/billing/plans/pro.cy.ts +497 -0
- package/tests/cypress/e2e/api/_core/billing/plans/starter.cy.ts +342 -0
- package/tests/cypress/e2e/api/_core/billing/portal.cy.ts +313 -0
- package/tests/cypress/e2e/api/_core/devtools/registries.bdd.md +300 -0
- package/tests/cypress/e2e/api/_core/devtools/registries.cy.ts +368 -0
- package/tests/cypress/e2e/api/_core/scheduled-actions/cron-endpoint.bdd.md +375 -0
- package/tests/cypress/e2e/api/_core/scheduled-actions/cron-endpoint.cy.ts +346 -0
- package/tests/cypress/e2e/api/_core/scheduled-actions/devtools-endpoint.bdd.md +451 -0
- package/tests/cypress/e2e/api/_core/scheduled-actions/devtools-endpoint.cy.ts +447 -0
- package/tests/cypress/e2e/api/_core/scheduled-actions/scheduling.bdd.md +649 -0
- package/tests/cypress/e2e/api/_core/scheduled-actions/scheduling.cy.ts +333 -0
- package/tests/cypress/e2e/api/_core/security/security-headers.cy.ts +601 -0
- package/tests/cypress/e2e/api/_core/settings/api-keys.crud.cy.ts +923 -0
- package/tests/cypress/e2e/api/_core/teams/teams-security.cy.ts +415 -0
- package/tests/cypress/e2e/api/_core/users/users-crud.cy.ts +469 -0
- package/tests/cypress/e2e/api/_core/users/users-metas.cy.ts +913 -0
- package/tests/cypress/e2e/api/_core/users/users-security.cy.ts +375 -0
- package/tests/cypress/e2e/api/entities/customers/customers-crud.cy.ts +648 -0
- package/tests/cypress/e2e/api/entities/customers/customers-metas.cy.ts +839 -0
- package/tests/cypress/e2e/api/entities/media/media-crud.cy.ts +600 -0
- package/tests/cypress/e2e/api/entities/media/media-role-permissions.cy.ts +617 -0
- package/tests/cypress/e2e/api/entities/media/media-team-isolation.cy.ts +464 -0
- package/tests/cypress/e2e/api/entities/pages/blocks-scope.cy.ts +396 -0
- package/tests/cypress/e2e/api/entities/pages/pages-crud.cy.ts +425 -0
- package/tests/cypress/e2e/api/entities/pages/pages-status.cy.ts +335 -0
- package/tests/cypress/e2e/api/entities/posts/post-categories-crud.cy.ts +610 -0
- package/tests/cypress/e2e/api/entities/posts/posts-crud.cy.ts +709 -0
- package/tests/cypress/e2e/api/entities/posts/posts-status.cy.ts +396 -0
- package/tests/cypress/e2e/api/entities/tasks/tasks-crud.cy.ts +602 -0
- package/tests/cypress/e2e/api/entities/tasks/tasks-metas.cy.ts +878 -0
- package/tests/cypress/e2e/patterns/patterns-in-pages.cy.ts +367 -0
- package/tests/cypress/e2e/uat/_core/auth/app-roles/developer-login.bdd.md +231 -0
- package/tests/cypress/e2e/uat/_core/auth/app-roles/developer-login.cy.ts +144 -0
- package/tests/cypress/e2e/uat/_core/auth/app-roles/superadmin-login.bdd.md +118 -0
- package/tests/cypress/e2e/uat/_core/auth/app-roles/superadmin-login.cy.ts +84 -0
- package/tests/cypress/e2e/uat/_core/auth/custom-roles/editor-login.bdd.md +288 -0
- package/tests/cypress/e2e/uat/_core/auth/custom-roles/editor-login.cy.ts +188 -0
- package/tests/cypress/e2e/uat/_core/auth/login-logout.bdd.md +160 -0
- package/tests/cypress/e2e/uat/_core/auth/login-logout.cy.ts +116 -0
- package/tests/cypress/e2e/uat/_core/auth/password-reset.bdd.md +289 -0
- package/tests/cypress/e2e/uat/_core/auth/password-reset.cy.ts +200 -0
- package/tests/cypress/e2e/uat/_core/auth/registration-control-invitation.cy.ts +176 -0
- package/tests/cypress/e2e/uat/_core/auth/registration-control-open.cy.ts +131 -0
- package/tests/cypress/e2e/uat/_core/auth/registration-control.cy.ts +140 -0
- package/tests/cypress/e2e/uat/_core/auth/team-roles/admin-login.bdd.md +225 -0
- package/tests/cypress/e2e/uat/_core/auth/team-roles/admin-login.cy.ts +148 -0
- package/tests/cypress/e2e/uat/_core/auth/team-roles/member-login.bdd.md +251 -0
- package/tests/cypress/e2e/uat/_core/auth/team-roles/member-login.cy.ts +163 -0
- package/tests/cypress/e2e/uat/_core/auth/team-roles/owner-login.bdd.md +231 -0
- package/tests/cypress/e2e/uat/_core/auth/team-roles/owner-login.cy.ts +141 -0
- package/tests/cypress/e2e/uat/_core/billing/extended.bdd.md +273 -0
- package/tests/cypress/e2e/uat/_core/billing/extended.cy.ts +209 -0
- package/tests/cypress/e2e/uat/_core/billing/feature-gates.bdd.md +407 -0
- package/tests/cypress/e2e/uat/_core/billing/feature-gates.cy.ts +307 -0
- package/tests/cypress/e2e/uat/_core/billing/page.bdd.md +329 -0
- package/tests/cypress/e2e/uat/_core/billing/page.cy.ts +250 -0
- package/tests/cypress/e2e/uat/_core/billing/status.bdd.md +190 -0
- package/tests/cypress/e2e/uat/_core/billing/status.cy.ts +145 -0
- package/tests/cypress/e2e/uat/_core/billing/team-switch.bdd.md +156 -0
- package/tests/cypress/e2e/uat/_core/billing/team-switch.cy.ts +122 -0
- package/tests/cypress/e2e/uat/_core/billing/usage.bdd.md +218 -0
- package/tests/cypress/e2e/uat/_core/billing/usage.cy.ts +176 -0
- package/tests/cypress/e2e/uat/_core/blocks/hero.bdd.md +124 -0
- package/tests/cypress/e2e/uat/_core/blocks/hero.cy.ts +56 -0
- package/tests/cypress/e2e/uat/_core/devtools/api-tester.cy.ts +390 -0
- package/tests/cypress/e2e/uat/_core/performance/suspense-loading.cy.ts +134 -0
- package/tests/cypress/e2e/uat/_core/scheduled-actions/devtools-ui.bdd.md +736 -0
- package/tests/cypress/e2e/uat/_core/scheduled-actions/devtools-ui.cy.ts +740 -0
- package/tests/cypress/e2e/uat/_core/teams/inline-edit.cy.ts +278 -0
- package/tests/cypress/e2e/uat/_core/teams/roles-matrix.bdd.md +553 -0
- package/tests/cypress/e2e/uat/_core/teams/roles-matrix.cy.ts +185 -0
- package/tests/cypress/e2e/uat/_core/teams/switcher.bdd.md +1151 -0
- package/tests/cypress/e2e/uat/_core/teams/switcher.cy.ts +497 -0
- package/tests/cypress/e2e/uat/_core/teams/team-switcher.md +198 -0
- package/tests/cypress/e2e/uat/entities/customers/member.bdd.md +275 -0
- package/tests/cypress/e2e/uat/entities/customers/member.cy.ts +122 -0
- package/tests/cypress/e2e/uat/entities/customers/owner.bdd.md +243 -0
- package/tests/cypress/e2e/uat/entities/customers/owner.cy.ts +165 -0
- package/tests/cypress/e2e/uat/entities/pages/block-crud.bdd.md +476 -0
- package/tests/cypress/e2e/uat/entities/pages/block-crud.cy.ts +486 -0
- package/tests/cypress/e2e/uat/entities/pages/block-editor.bdd.md +460 -0
- package/tests/cypress/e2e/uat/entities/pages/block-editor.cy.ts +301 -0
- package/tests/cypress/e2e/uat/entities/pages/list.bdd.md +432 -0
- package/tests/cypress/e2e/uat/entities/pages/list.cy.ts +273 -0
- package/tests/cypress/e2e/uat/entities/pages/public-rendering.bdd.md +696 -0
- package/tests/cypress/e2e/uat/entities/pages/public-rendering.cy.ts +340 -0
- package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.bdd.md +161 -0
- package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.cy.ts +104 -0
- package/tests/cypress/e2e/uat/entities/posts/categories.bdd.md +375 -0
- package/tests/cypress/e2e/uat/entities/posts/categories.cy.ts +241 -0
- package/tests/cypress/e2e/uat/entities/posts/editor.bdd.md +429 -0
- package/tests/cypress/e2e/uat/entities/posts/editor.cy.ts +257 -0
- package/tests/cypress/e2e/uat/entities/posts/list.bdd.md +340 -0
- package/tests/cypress/e2e/uat/entities/posts/list.cy.ts +177 -0
- package/tests/cypress/e2e/uat/entities/posts/public.bdd.md +614 -0
- package/tests/cypress/e2e/uat/entities/posts/public.cy.ts +249 -0
- package/tests/cypress/e2e/uat/entities/tasks/member.bdd.md +222 -0
- package/tests/cypress/e2e/uat/entities/tasks/member.cy.ts +165 -0
- package/tests/cypress/e2e/uat/entities/tasks/owner.bdd.md +419 -0
- package/tests/cypress/e2e/uat/entities/tasks/owner.cy.ts +191 -0
- package/tests/cypress/e2e/uat/features/roles/editor-role.bdd.md +552 -0
- package/tests/cypress/e2e/uat/features/roles/editor-role.cy.ts +210 -0
- package/tests/cypress/e2e/uat/features/roles/member-restrictions.bdd.md +450 -0
- package/tests/cypress/e2e/uat/features/roles/member-restrictions.cy.ts +189 -0
- package/tests/cypress/e2e/uat/features/roles/owner-full-crud.bdd.md +530 -0
- package/tests/cypress/e2e/uat/features/roles/owner-full-crud.cy.ts +247 -0
- package/tests/cypress/fixtures/blocks.json +218 -0
- package/tests/cypress/fixtures/entities.json +87 -0
- package/tests/cypress/fixtures/page-builder.json +21 -0
- package/tests/cypress/src/components/CategoriesPOM.ts +382 -0
- package/tests/cypress/src/components/CustomersPOM.ts +439 -0
- package/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
- package/tests/cypress/src/components/EntityForm.ts +375 -0
- package/tests/cypress/src/components/EntityList.ts +389 -0
- package/tests/cypress/src/components/PageBuilderPOM.ts +710 -0
- package/tests/cypress/src/components/PostEditorPOM.ts +370 -0
- package/tests/cypress/src/components/PostsListPOM.ts +223 -0
- package/tests/cypress/src/components/PublicPagePOM.ts +447 -0
- package/tests/cypress/src/components/PublicPostPOM.ts +146 -0
- package/tests/cypress/src/components/TasksPOM.ts +272 -0
- package/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
- package/tests/cypress/src/components/index.ts +21 -0
- package/tests/cypress/src/controllers/ApiKeysAPIController.js +178 -0
- package/tests/cypress/src/controllers/BaseAPIController.js +317 -0
- package/tests/cypress/src/controllers/CustomerAPIController.js +251 -0
- package/tests/cypress/src/controllers/MediaAPIController.js +231 -0
- package/tests/cypress/src/controllers/PagesAPIController.js +226 -0
- package/tests/cypress/src/controllers/PostsAPIController.js +250 -0
- package/tests/cypress/src/controllers/TaskAPIController.js +240 -0
- package/tests/cypress/src/controllers/UsersAPIController.js +242 -0
- package/tests/cypress/src/controllers/index.js +25 -0
- package/tests/cypress/src/core/AuthPOM.ts +450 -0
- package/tests/cypress/src/core/BasePOM.ts +33 -0
- package/tests/cypress/src/core/BlockEditorBasePOM.ts +874 -0
- package/tests/cypress/src/core/DashboardEntityPOM.ts +41 -0
- package/tests/cypress/src/core/index.ts +14 -0
- package/tests/cypress/src/entities/CustomersPOM.ts +172 -0
- package/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/tests/cypress/src/entities/PatternsPOM.ts +329 -0
- package/tests/cypress/src/entities/PostsPOM.ts +137 -0
- package/tests/cypress/src/entities/TasksPOM.ts +246 -0
- package/tests/cypress/src/entities/index.ts +16 -0
- package/tests/cypress/src/features/BillingPOM.ts +385 -0
- package/tests/cypress/src/features/DashboardPOM.ts +271 -0
- package/tests/cypress/src/features/DevtoolsPOM.ts +750 -0
- package/tests/cypress/src/features/PageBuilderPOM.ts +283 -0
- package/tests/cypress/src/features/PostEditorPOM.ts +313 -0
- package/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
- package/tests/cypress/src/features/SettingsPOM.ts +707 -0
- package/tests/cypress/src/features/SuperadminPOM.ts +851 -0
- package/tests/cypress/src/features/SuperadminTeamRolesPOM.ts +285 -0
- package/tests/cypress/src/features/index.ts +28 -0
- package/tests/cypress/src/helpers/ApiInterceptor.ts +20 -0
- package/tests/cypress/src/index.ts +101 -0
- package/tests/cypress/src/pages/dashboard/Dashboard.js +677 -0
- package/tests/cypress/src/pages/dashboard/DashboardPage.js +43 -0
- package/tests/cypress/src/pages/dashboard/DashboardStats.js +546 -0
- package/tests/cypress/src/pages/dashboard/index.js +6 -0
- package/tests/cypress/src/pages/index.js +5 -0
- package/tests/cypress/src/pages/public/FeaturesPage.js +28 -0
- package/tests/cypress/src/pages/public/LandingPage.js +69 -0
- package/tests/cypress/src/pages/public/PricingPage.js +33 -0
- package/tests/cypress/src/pages/public/index.js +6 -0
- package/tests/cypress/src/selectors.ts +46 -0
- package/tests/cypress/src/session-helpers.ts +518 -0
- package/tests/cypress/support/doc-commands.ts +260 -0
- package/tests/cypress/support/e2e.ts +90 -0
- package/tests/cypress.config.ts +178 -0
- package/tests/jest/__mocks__/@nextsparkjs/core/components/ui/badge.js +16 -0
- package/tests/jest/__mocks__/@nextsparkjs/core/lib/db.js +11 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/permissions-registry.ts +160 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/theme-registry.ts +68 -0
- package/tests/jest/__mocks__/jose.js +22 -0
- package/tests/jest/__mocks__/next/image.js +15 -0
- package/tests/jest/__mocks__/next-server.js +56 -0
- package/tests/jest/components/post-header.test.tsx +377 -0
- package/tests/jest/jest.config.cjs +154 -0
- package/tests/jest/langchain/COVERAGE.md +372 -0
- package/tests/jest/langchain/guardrails.test.ts +465 -0
- package/tests/jest/langchain/streaming.test.ts +370 -0
- package/tests/jest/langchain/token-tracker.test.ts +455 -0
- package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
- package/tests/jest/langchain/tracer.test.ts +823 -0
- package/tests/jest/services/tasks.service.test.ts +707 -0
- package/tests/jest/setup.ts +170 -0
- package/tests/jest/tsconfig.jest.json +6 -0
- package/tests/jest/validation/categories.test.ts +429 -0
- package/tests/jest/validation/posts.test.ts +546 -0
- package/tests/tsconfig.json +21 -0
- /package/docs/{02-features → public/02-features}/01-components.md +0 -0
- /package/docs/{02-features → public/02-features}/02-styling.md +0 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
---
|
|
2
|
+
feature: Password Reset Flow
|
|
3
|
+
priority: critical
|
|
4
|
+
tags: [auth, password-reset, security, user-flow]
|
|
5
|
+
grepTags: [uat, feat-auth, password-reset]
|
|
6
|
+
coverage: 8
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Password Reset Flow
|
|
10
|
+
|
|
11
|
+
> Tests for the password reset flow including page access, form validation, submission, and error handling. Actual email delivery is not tested as it requires external service integration.
|
|
12
|
+
|
|
13
|
+
## @test PWD-RESET-001: Access Password Reset Page
|
|
14
|
+
|
|
15
|
+
### Metadata
|
|
16
|
+
- **Priority:** Critical
|
|
17
|
+
- **Type:** Smoke
|
|
18
|
+
- **Tags:** password-reset, navigation
|
|
19
|
+
- **Grep:** `@smoke`
|
|
20
|
+
|
|
21
|
+
```gherkin:en
|
|
22
|
+
Scenario: Access password reset page from login
|
|
23
|
+
|
|
24
|
+
Given I am on the login page
|
|
25
|
+
When I click on the forgot password link
|
|
26
|
+
Then I should be on /forgot-password
|
|
27
|
+
And the password reset form should be visible
|
|
28
|
+
And the email input should be visible
|
|
29
|
+
And the submit button should be visible
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```gherkin:es
|
|
33
|
+
Scenario: Acceder a pagina de reset de password desde login
|
|
34
|
+
|
|
35
|
+
Given estoy en la pagina de login
|
|
36
|
+
When hago click en el enlace de olvide mi password
|
|
37
|
+
Then deberia estar en /forgot-password
|
|
38
|
+
And el formulario de reset deberia estar visible
|
|
39
|
+
And el input de email deberia estar visible
|
|
40
|
+
And el boton de enviar deberia estar visible
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Expected Results
|
|
44
|
+
- Forgot password link works
|
|
45
|
+
- Password reset page loads
|
|
46
|
+
- All form elements visible
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## @test PWD-RESET-002: Direct URL Access
|
|
51
|
+
|
|
52
|
+
### Metadata
|
|
53
|
+
- **Priority:** Normal
|
|
54
|
+
- **Type:** Smoke
|
|
55
|
+
- **Tags:** password-reset, direct-access
|
|
56
|
+
- **Grep:** `@smoke`
|
|
57
|
+
|
|
58
|
+
```gherkin:en
|
|
59
|
+
Scenario: Access password reset page directly via URL
|
|
60
|
+
|
|
61
|
+
Given I visit /forgot-password directly
|
|
62
|
+
Then the password reset container should be visible
|
|
63
|
+
And the email input should be visible
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```gherkin:es
|
|
67
|
+
Scenario: Acceder a pagina de reset directamente via URL
|
|
68
|
+
|
|
69
|
+
Given visito /forgot-password directamente
|
|
70
|
+
Then el contenedor de reset deberia estar visible
|
|
71
|
+
And el input de email deberia estar visible
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Expected Results
|
|
75
|
+
- Direct URL access works
|
|
76
|
+
- No authentication required
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## @test PWD-RESET-003: Submit Valid Email
|
|
81
|
+
|
|
82
|
+
### Metadata
|
|
83
|
+
- **Priority:** Critical
|
|
84
|
+
- **Type:** Smoke
|
|
85
|
+
- **Tags:** password-reset, submit
|
|
86
|
+
- **Grep:** `@smoke`
|
|
87
|
+
|
|
88
|
+
```gherkin:en
|
|
89
|
+
Scenario: Submit password reset with valid email format
|
|
90
|
+
|
|
91
|
+
Given I am on the password reset page
|
|
92
|
+
When I enter a valid email format (user@example.com)
|
|
93
|
+
And I click the submit button
|
|
94
|
+
Then I should see a success message
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```gherkin:es
|
|
98
|
+
Scenario: Enviar reset de password con email valido
|
|
99
|
+
|
|
100
|
+
Given estoy en la pagina de reset de password
|
|
101
|
+
When ingreso un email con formato valido (user@example.com)
|
|
102
|
+
And hago click en el boton de enviar
|
|
103
|
+
Then deberia ver un mensaje de exito
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Expected Results
|
|
107
|
+
- Form submits successfully
|
|
108
|
+
- Success message displayed
|
|
109
|
+
- No email enumeration (same message for existing/non-existing)
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## @test PWD-RESET-004: Validate Empty Email
|
|
114
|
+
|
|
115
|
+
### Metadata
|
|
116
|
+
- **Priority:** High
|
|
117
|
+
- **Type:** Validation
|
|
118
|
+
- **Tags:** password-reset, validation, empty
|
|
119
|
+
|
|
120
|
+
```gherkin:en
|
|
121
|
+
Scenario: Show error for empty email field
|
|
122
|
+
|
|
123
|
+
Given I am on the password reset page
|
|
124
|
+
When I click submit without entering an email
|
|
125
|
+
Then I should see a required field error
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
```gherkin:es
|
|
129
|
+
Scenario: Mostrar error para campo email vacio
|
|
130
|
+
|
|
131
|
+
Given estoy en la pagina de reset de password
|
|
132
|
+
When hago click en enviar sin ingresar email
|
|
133
|
+
Then deberia ver un error de campo requerido
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Expected Results
|
|
137
|
+
- Validation error displayed
|
|
138
|
+
- Form not submitted
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## @test PWD-RESET-005: Validate Invalid Email Format
|
|
143
|
+
|
|
144
|
+
### Metadata
|
|
145
|
+
- **Priority:** High
|
|
146
|
+
- **Type:** Validation
|
|
147
|
+
- **Tags:** password-reset, validation, format
|
|
148
|
+
|
|
149
|
+
```gherkin:en
|
|
150
|
+
Scenario: Show error for invalid email format
|
|
151
|
+
|
|
152
|
+
Given I am on the password reset page
|
|
153
|
+
When I enter an invalid email format (not-an-email)
|
|
154
|
+
And I click the submit button
|
|
155
|
+
Then I should see an invalid email error
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```gherkin:es
|
|
159
|
+
Scenario: Mostrar error para formato de email invalido
|
|
160
|
+
|
|
161
|
+
Given estoy en la pagina de reset de password
|
|
162
|
+
When ingreso un formato de email invalido (not-an-email)
|
|
163
|
+
And hago click en el boton de enviar
|
|
164
|
+
Then deberia ver un error de email invalido
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Expected Results
|
|
168
|
+
- Format validation works
|
|
169
|
+
- Clear error message
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## @test PWD-RESET-006: Back to Login Link
|
|
174
|
+
|
|
175
|
+
### Metadata
|
|
176
|
+
- **Priority:** Normal
|
|
177
|
+
- **Type:** Navigation
|
|
178
|
+
- **Tags:** password-reset, navigation
|
|
179
|
+
|
|
180
|
+
```gherkin:en
|
|
181
|
+
Scenario: Navigate back to login page
|
|
182
|
+
|
|
183
|
+
Given I am on the password reset page
|
|
184
|
+
When I click the back to login link
|
|
185
|
+
Then I should be on the login page
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
```gherkin:es
|
|
189
|
+
Scenario: Navegar de vuelta a pagina de login
|
|
190
|
+
|
|
191
|
+
Given estoy en la pagina de reset de password
|
|
192
|
+
When hago click en el enlace de volver a login
|
|
193
|
+
Then deberia estar en la pagina de login
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Expected Results
|
|
197
|
+
- Back link works
|
|
198
|
+
- Returns to login page
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## @test PWD-RESET-007: Submit with Known Test Email
|
|
203
|
+
|
|
204
|
+
### Metadata
|
|
205
|
+
- **Priority:** High
|
|
206
|
+
- **Type:** Regression
|
|
207
|
+
- **Tags:** password-reset, existing-user
|
|
208
|
+
|
|
209
|
+
```gherkin:en
|
|
210
|
+
Scenario: Handle submission with existing user email
|
|
211
|
+
|
|
212
|
+
Given I am on the password reset page
|
|
213
|
+
When I enter a known test email (carlos.mendoza@nextspark.dev)
|
|
214
|
+
And I click the submit button
|
|
215
|
+
Then I should see a success message
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```gherkin:es
|
|
219
|
+
Scenario: Manejar envio con email de usuario existente
|
|
220
|
+
|
|
221
|
+
Given estoy en la pagina de reset de password
|
|
222
|
+
When ingreso un email de prueba conocido (carlos.mendoza@nextspark.dev)
|
|
223
|
+
And hago click en el boton de enviar
|
|
224
|
+
Then deberia ver un mensaje de exito
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Expected Results
|
|
228
|
+
- Same success message as non-existing email
|
|
229
|
+
- No email enumeration vulnerability
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
## @test PWD-RESET-008: Form Keyboard Accessibility
|
|
234
|
+
|
|
235
|
+
### Metadata
|
|
236
|
+
- **Priority:** Normal
|
|
237
|
+
- **Type:** Accessibility
|
|
238
|
+
- **Tags:** password-reset, keyboard, a11y
|
|
239
|
+
|
|
240
|
+
```gherkin:en
|
|
241
|
+
Scenario: Submit form with Enter key
|
|
242
|
+
|
|
243
|
+
Given I am on the password reset page
|
|
244
|
+
When I enter an email and press Enter
|
|
245
|
+
Then the form should be submitted
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
```gherkin:es
|
|
249
|
+
Scenario: Enviar formulario con tecla Enter
|
|
250
|
+
|
|
251
|
+
Given estoy en la pagina de reset de password
|
|
252
|
+
When ingreso un email y presiono Enter
|
|
253
|
+
Then el formulario deberia ser enviado
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Expected Results
|
|
257
|
+
- Enter key submits form
|
|
258
|
+
- Keyboard navigation works
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
## UI Elements
|
|
263
|
+
|
|
264
|
+
| Element | Selector | Description |
|
|
265
|
+
|---------|----------|-------------|
|
|
266
|
+
| Forgot Password Link | `[data-cy="login-forgot-password"]` | Link on login page |
|
|
267
|
+
| Form | `[data-cy="forgot-password-form"]` | Password reset form |
|
|
268
|
+
| Email Input | `[data-cy="forgot-password-email"]` | Email input field |
|
|
269
|
+
| Submit Button | `[data-cy="forgot-password-submit"]` | Submit button |
|
|
270
|
+
| Success Message | `[data-cy="forgot-password-success"]` | Success message |
|
|
271
|
+
| Error Message | `[data-cy="forgot-password-error"]` | Error message |
|
|
272
|
+
| Back to Login | `[data-cy="forgot-password-back"]` | Back to login link |
|
|
273
|
+
|
|
274
|
+
> Note: Tests use `AuthPOM` from `src/core/AuthPOM.ts` which loads selectors from `fixtures/selectors/auth.json`
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Summary
|
|
279
|
+
|
|
280
|
+
| Test ID | Block | Description | Tags |
|
|
281
|
+
|---------|-------|-------------|------|
|
|
282
|
+
| PWD-RESET-001 | Access | Page access from login | `@smoke` |
|
|
283
|
+
| PWD-RESET-002 | Access | Direct URL access | `@smoke` |
|
|
284
|
+
| PWD-RESET-003 | Submit | Submit valid email | `@smoke` |
|
|
285
|
+
| PWD-RESET-004 | Validation | Empty email error | |
|
|
286
|
+
| PWD-RESET-005 | Validation | Invalid format error | |
|
|
287
|
+
| PWD-RESET-006 | Navigation | Back to login | |
|
|
288
|
+
| PWD-RESET-007 | Submit | Existing user email | |
|
|
289
|
+
| PWD-RESET-008 | A11y | Keyboard accessibility | |
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/// <reference types="cypress" />
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Password Reset Flow Tests
|
|
5
|
+
*
|
|
6
|
+
* Tests the complete password reset flow:
|
|
7
|
+
* - Request password reset link
|
|
8
|
+
* - Validate form fields
|
|
9
|
+
* - Handle errors (invalid email, rate limiting)
|
|
10
|
+
* - Success message display
|
|
11
|
+
*
|
|
12
|
+
* Note: Actual email delivery and token validation are not tested here
|
|
13
|
+
* as they require external email service integration.
|
|
14
|
+
* Tests verify up to the point of email send request.
|
|
15
|
+
*
|
|
16
|
+
* Tags: @uat, @feat-auth, @password-reset
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import * as allure from 'allure-cypress'
|
|
20
|
+
|
|
21
|
+
import { AuthPOM } from '../../../../src/core/AuthPOM'
|
|
22
|
+
|
|
23
|
+
describe('Authentication - Password Reset Flow', {
|
|
24
|
+
tags: ['@uat', '@feat-auth', '@password-reset']
|
|
25
|
+
}, () => {
|
|
26
|
+
const auth = new AuthPOM()
|
|
27
|
+
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
allure.epic('Authentication')
|
|
30
|
+
allure.feature('Password Reset')
|
|
31
|
+
// Clear any existing session
|
|
32
|
+
cy.clearCookies()
|
|
33
|
+
cy.clearLocalStorage()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
describe('PWD-RESET-001: Access Password Reset Page', { tags: '@smoke' }, () => {
|
|
37
|
+
it('should access password reset page from login', { tags: '@smoke' }, () => {
|
|
38
|
+
allure.severity('critical')
|
|
39
|
+
allure.story('Page Access')
|
|
40
|
+
|
|
41
|
+
// 1. Visit login page
|
|
42
|
+
auth.visitLogin()
|
|
43
|
+
|
|
44
|
+
// 2. Show email form (forgot password link is inside email form section)
|
|
45
|
+
auth.showEmailLogin()
|
|
46
|
+
auth.waitForLoginForm()
|
|
47
|
+
|
|
48
|
+
// 3. Click on forgot password link
|
|
49
|
+
auth.clickForgotPassword()
|
|
50
|
+
|
|
51
|
+
// 4. Validate password reset page
|
|
52
|
+
cy.url().should('include', '/forgot-password')
|
|
53
|
+
cy.get(auth.selectors.forgotPasswordForm).should('be.visible')
|
|
54
|
+
cy.get(auth.selectors.forgotPasswordEmail).should('be.visible')
|
|
55
|
+
cy.get(auth.selectors.forgotPasswordSubmit).should('be.visible')
|
|
56
|
+
|
|
57
|
+
cy.log('✅ Password reset page accessible')
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
describe('PWD-RESET-002: Direct URL Access', { tags: '@smoke' }, () => {
|
|
62
|
+
it('should access password reset page directly via URL', { tags: '@smoke' }, () => {
|
|
63
|
+
allure.severity('normal')
|
|
64
|
+
allure.story('Direct Access')
|
|
65
|
+
|
|
66
|
+
// 1. Visit directly
|
|
67
|
+
auth.visitForgotPassword()
|
|
68
|
+
|
|
69
|
+
// 2. Validate page elements
|
|
70
|
+
cy.get(auth.selectors.forgotPasswordForm).should('be.visible')
|
|
71
|
+
cy.get(auth.selectors.forgotPasswordEmail).should('be.visible')
|
|
72
|
+
|
|
73
|
+
cy.log('✅ Direct access to password reset works')
|
|
74
|
+
})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
describe('PWD-RESET-003: Submit Valid Email', { tags: '@smoke' }, () => {
|
|
78
|
+
it('should show success message for valid email format', { tags: '@smoke' }, () => {
|
|
79
|
+
allure.severity('critical')
|
|
80
|
+
allure.story('Submit Request')
|
|
81
|
+
|
|
82
|
+
// 1. Visit password reset page
|
|
83
|
+
auth.visitForgotPassword()
|
|
84
|
+
|
|
85
|
+
// 2. Request password reset
|
|
86
|
+
auth.requestPasswordReset('user@example.com')
|
|
87
|
+
|
|
88
|
+
// 3. Should show success message (even if email doesn't exist for security)
|
|
89
|
+
auth.waitForPasswordResetSuccess()
|
|
90
|
+
|
|
91
|
+
cy.log('✅ Password reset request submitted successfully')
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
describe('PWD-RESET-004: Validate Empty Email', () => {
|
|
96
|
+
it('should show error for empty email field', () => {
|
|
97
|
+
allure.severity('high')
|
|
98
|
+
allure.story('Validation')
|
|
99
|
+
|
|
100
|
+
// 1. Visit password reset page
|
|
101
|
+
auth.visitForgotPassword()
|
|
102
|
+
|
|
103
|
+
// 2. Submit without entering email
|
|
104
|
+
cy.get(auth.selectors.forgotPasswordSubmit).click()
|
|
105
|
+
|
|
106
|
+
// 3. Should show Zod validation error in UI
|
|
107
|
+
// The form uses react-hook-form with zod validation
|
|
108
|
+
// Empty email triggers validation error from zod schema
|
|
109
|
+
cy.contains('.text-destructive', 'Please enter a valid email address').should('be.visible')
|
|
110
|
+
|
|
111
|
+
cy.log('✅ Empty email validation works')
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
describe('PWD-RESET-005: Validate Invalid Email Format', () => {
|
|
116
|
+
it('should show error for invalid email format', () => {
|
|
117
|
+
allure.severity('high')
|
|
118
|
+
allure.story('Validation')
|
|
119
|
+
|
|
120
|
+
// 1. Visit password reset page
|
|
121
|
+
auth.visitForgotPassword()
|
|
122
|
+
|
|
123
|
+
// 2. Enter invalid email format
|
|
124
|
+
cy.get(auth.selectors.forgotPasswordEmail).type('not-an-email')
|
|
125
|
+
|
|
126
|
+
// 3. Submit form
|
|
127
|
+
cy.get(auth.selectors.forgotPasswordSubmit).click()
|
|
128
|
+
|
|
129
|
+
// 4. Should show validation error (HTML5 or custom)
|
|
130
|
+
cy.get(auth.selectors.forgotPasswordEmail).then(($input) => {
|
|
131
|
+
const input = $input[0] as HTMLInputElement
|
|
132
|
+
if (input.validity) {
|
|
133
|
+
expect(input.validity.valid).to.be.false
|
|
134
|
+
}
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
cy.log('✅ Invalid email format validation works')
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
describe('PWD-RESET-006: Back to Login Link', () => {
|
|
142
|
+
it('should navigate back to login page', () => {
|
|
143
|
+
allure.severity('normal')
|
|
144
|
+
allure.story('Navigation')
|
|
145
|
+
|
|
146
|
+
// 1. Visit password reset page
|
|
147
|
+
auth.visitForgotPassword()
|
|
148
|
+
|
|
149
|
+
// 2. Click back to login
|
|
150
|
+
auth.backToLogin()
|
|
151
|
+
|
|
152
|
+
// 3. Should be on login page
|
|
153
|
+
auth.assertOnLoginPage()
|
|
154
|
+
|
|
155
|
+
cy.log('✅ Back to login navigation works')
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
describe('PWD-RESET-007: Submit with Known Test Email', () => {
|
|
160
|
+
it('should handle submission with existing user email', () => {
|
|
161
|
+
allure.severity('high')
|
|
162
|
+
allure.story('Submit Request')
|
|
163
|
+
|
|
164
|
+
// 1. Visit password reset page
|
|
165
|
+
auth.visitForgotPassword()
|
|
166
|
+
|
|
167
|
+
// 2. Request reset for known test email
|
|
168
|
+
auth.requestPasswordReset('carlos.mendoza@nextspark.dev')
|
|
169
|
+
|
|
170
|
+
// 3. Should show success (same message for security - no email enumeration)
|
|
171
|
+
auth.waitForPasswordResetSuccess()
|
|
172
|
+
|
|
173
|
+
cy.log('✅ Password reset for existing user handled correctly')
|
|
174
|
+
})
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
describe('PWD-RESET-008: Form Keyboard Accessibility', () => {
|
|
178
|
+
it('should submit form with Enter key', () => {
|
|
179
|
+
allure.severity('normal')
|
|
180
|
+
allure.story('Accessibility')
|
|
181
|
+
|
|
182
|
+
// 1. Visit password reset page
|
|
183
|
+
auth.visitForgotPassword()
|
|
184
|
+
|
|
185
|
+
// 2. Enter email and press Enter
|
|
186
|
+
cy.get(auth.selectors.forgotPasswordEmail)
|
|
187
|
+
.type('user@example.com{enter}')
|
|
188
|
+
|
|
189
|
+
// 3. Should process submission and show success (async operation)
|
|
190
|
+
// Wait for the success message to appear after API call completes
|
|
191
|
+
auth.waitForPasswordResetSuccess()
|
|
192
|
+
|
|
193
|
+
cy.log('✅ Keyboard submission works')
|
|
194
|
+
})
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
after(() => {
|
|
198
|
+
cy.log('✅ Password reset flow tests completed')
|
|
199
|
+
})
|
|
200
|
+
})
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/// <reference types="cypress" />
|
|
2
|
+
|
|
3
|
+
import * as allure from 'allure-cypress'
|
|
4
|
+
|
|
5
|
+
import { DEFAULT_THEME_USERS } from '../../../../src/session-helpers'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Registration Control Tests - Invitation-Only Mode
|
|
9
|
+
*
|
|
10
|
+
* Verifies registration mode enforcement when mode is 'invitation-only'.
|
|
11
|
+
* Tests: signup redirect, login page visibility, API blocking, existing user login.
|
|
12
|
+
*
|
|
13
|
+
* These tests detect the current registration mode and skip if not 'invitation-only'.
|
|
14
|
+
* Detection: invitation-only mode redirects /signup AND shows email login on /login
|
|
15
|
+
* (unlike domain-restricted which hides email login).
|
|
16
|
+
*/
|
|
17
|
+
describe('Registration Control - Invitation-Only Mode', {
|
|
18
|
+
tags: ['@uat', '@feat-auth', '@security', '@regression']
|
|
19
|
+
}, () => {
|
|
20
|
+
const TEST_PASSWORD = Cypress.env('TEST_PASSWORD') || 'Test1234'
|
|
21
|
+
|
|
22
|
+
before(() => {
|
|
23
|
+
// Detect invitation-only mode:
|
|
24
|
+
// 1. /signup redirects (shared with domain-restricted)
|
|
25
|
+
// 2. /login shows email form (NOT shared with domain-restricted, which hides it)
|
|
26
|
+
cy.request({
|
|
27
|
+
url: '/signup',
|
|
28
|
+
followRedirect: false,
|
|
29
|
+
failOnStatusCode: false,
|
|
30
|
+
}).then((signupResponse) => {
|
|
31
|
+
if (signupResponse.status < 300 || signupResponse.status >= 400) {
|
|
32
|
+
// /signup is accessible — this is 'open' mode, skip
|
|
33
|
+
Cypress.runner.stop()
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// /signup redirects — could be domain-restricted or invitation-only
|
|
38
|
+
// Check login page for email form to distinguish
|
|
39
|
+
cy.visit('/login')
|
|
40
|
+
cy.get('body').then(($body) => {
|
|
41
|
+
// In domain-restricted mode, email login is hidden (no showEmail toggle, no form)
|
|
42
|
+
// In invitation-only mode, email login IS shown
|
|
43
|
+
const hasEmailForm = $body.find('[data-cy="auth.login.form"]').length > 0
|
|
44
|
+
const hasShowEmail = $body.find('[data-cy="auth.login.showEmail"]').length > 0
|
|
45
|
+
|
|
46
|
+
if (!hasEmailForm && !hasShowEmail) {
|
|
47
|
+
// No email login at all — this is domain-restricted, not invitation-only
|
|
48
|
+
Cypress.runner.stop()
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
allure.epic('UAT')
|
|
56
|
+
allure.feature('Registration Control')
|
|
57
|
+
cy.clearCookies()
|
|
58
|
+
cy.clearLocalStorage()
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
describe('REG_INV_001: Signup page redirects in invitation-only mode', () => {
|
|
62
|
+
it('should redirect /signup to /login', () => {
|
|
63
|
+
allure.story('Signup Redirect')
|
|
64
|
+
allure.severity('critical')
|
|
65
|
+
|
|
66
|
+
cy.log('1. Visit /signup')
|
|
67
|
+
cy.visit('/signup', { failOnStatusCode: false })
|
|
68
|
+
|
|
69
|
+
cy.log('2. Should redirect to /login')
|
|
70
|
+
cy.url().should('include', '/login')
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('REG_INV_002: Login page shows email login but no signup link', () => {
|
|
75
|
+
it('should show email login and hide signup link', () => {
|
|
76
|
+
allure.story('Login Page Visibility')
|
|
77
|
+
allure.severity('critical')
|
|
78
|
+
|
|
79
|
+
cy.log('1. Visit /login')
|
|
80
|
+
cy.visit('/login')
|
|
81
|
+
|
|
82
|
+
cy.log('2. Email login should be available')
|
|
83
|
+
cy.get('body').then(($body) => {
|
|
84
|
+
if ($body.find('[data-cy="auth.login.showEmail"]').length) {
|
|
85
|
+
cy.get('[data-cy="auth.login.showEmail"]').click()
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
cy.get('[data-cy="auth.login.form"]').should('exist')
|
|
89
|
+
|
|
90
|
+
cy.log('3. Signup link should NOT exist')
|
|
91
|
+
cy.get('[data-cy="auth.login.signupLink"]').should('not.exist')
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
describe('REG_INV_003: API blocks email signup in invitation-only mode', () => {
|
|
96
|
+
it('should return 403 for email signup attempt', () => {
|
|
97
|
+
allure.story('API Signup Blocking')
|
|
98
|
+
allure.severity('critical')
|
|
99
|
+
|
|
100
|
+
cy.log('1. POST /api/auth/sign-up/email with new user data')
|
|
101
|
+
cy.request({
|
|
102
|
+
method: 'POST',
|
|
103
|
+
url: '/api/auth/sign-up/email',
|
|
104
|
+
body: {
|
|
105
|
+
name: 'Test Uninvited User',
|
|
106
|
+
email: 'uninvited@some-domain.com',
|
|
107
|
+
password: 'TestPassword123',
|
|
108
|
+
},
|
|
109
|
+
failOnStatusCode: false,
|
|
110
|
+
}).then((response) => {
|
|
111
|
+
cy.log(`Response status: ${response.status}`)
|
|
112
|
+
// Should be blocked — 403 or 500 (from SIGNUP_RESTRICTED error)
|
|
113
|
+
expect(response.status).to.be.oneOf([403, 500])
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
describe('REG_INV_004: API blocks alternative signup endpoints', () => {
|
|
119
|
+
it('should block signup via alternative endpoints', () => {
|
|
120
|
+
allure.story('API Signup Blocking')
|
|
121
|
+
allure.severity('normal')
|
|
122
|
+
|
|
123
|
+
const signupPayload = {
|
|
124
|
+
name: 'Test Uninvited User',
|
|
125
|
+
email: 'uninvited@some-domain.com',
|
|
126
|
+
password: 'TestPassword123',
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const endpoints = [
|
|
130
|
+
'/api/auth/sign-up/email',
|
|
131
|
+
'/api/auth/sign-up/credentials',
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
endpoints.forEach((endpoint) => {
|
|
135
|
+
cy.log(`Testing: POST ${endpoint}`)
|
|
136
|
+
cy.request({
|
|
137
|
+
method: 'POST',
|
|
138
|
+
url: endpoint,
|
|
139
|
+
body: signupPayload,
|
|
140
|
+
failOnStatusCode: false,
|
|
141
|
+
}).then((response) => {
|
|
142
|
+
cy.log(`${endpoint} → ${response.status}`)
|
|
143
|
+
// Should be blocked (403/500 for blocked signup, 404 for non-existent)
|
|
144
|
+
expect(response.status).to.be.oneOf([403, 404, 422, 500])
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
describe('REG_INV_005: Existing user can still login with email+password', () => {
|
|
151
|
+
it('should allow existing user to sign in via API', () => {
|
|
152
|
+
allure.story('Existing User Login')
|
|
153
|
+
allure.severity('critical')
|
|
154
|
+
|
|
155
|
+
const existingUser = DEFAULT_THEME_USERS.OWNER
|
|
156
|
+
|
|
157
|
+
cy.log(`1. POST /api/auth/sign-in/email with existing user: ${existingUser}`)
|
|
158
|
+
cy.request({
|
|
159
|
+
method: 'POST',
|
|
160
|
+
url: '/api/auth/sign-in/email',
|
|
161
|
+
body: {
|
|
162
|
+
email: existingUser,
|
|
163
|
+
password: TEST_PASSWORD,
|
|
164
|
+
},
|
|
165
|
+
failOnStatusCode: false,
|
|
166
|
+
}).then((response) => {
|
|
167
|
+
cy.log(`Response status: ${response.status}`)
|
|
168
|
+
expect(response.status).to.eq(200)
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
after(() => {
|
|
174
|
+
cy.log('Registration control (invitation-only mode) tests completed')
|
|
175
|
+
})
|
|
176
|
+
})
|