@nextsparkjs/theme-default 0.1.0-beta.17 → 0.1.0-beta.170
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,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DashboardEntityPOM - Theme-specific base class for entity Page Object Models
|
|
3
|
+
*
|
|
4
|
+
* Extends DashboardEntityPOMCore from @nextsparkjs/testing and implements
|
|
5
|
+
* the abstract cySelector method with theme-specific selectors.
|
|
6
|
+
*
|
|
7
|
+
* Adds theme-specific functionality:
|
|
8
|
+
* - Entity config validation from fixtures
|
|
9
|
+
* - Convenience aliases (goToList, goToCreate, etc.)
|
|
10
|
+
* - Additional assertions
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* class TasksPOM extends DashboardEntityPOM {
|
|
14
|
+
* constructor() {
|
|
15
|
+
* super('tasks')
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* fillTaskForm(data: TaskFormData) {
|
|
19
|
+
* // Entity-specific form handling
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { DashboardEntityPOMCore, type EntityConfig } from '@nextsparkjs/testing/pom'
|
|
25
|
+
import { type Replacements } from '@nextsparkjs/core/selectors'
|
|
26
|
+
import { cySelector } from '../selectors'
|
|
27
|
+
|
|
28
|
+
export abstract class DashboardEntityPOM extends DashboardEntityPOMCore {
|
|
29
|
+
/**
|
|
30
|
+
* Implement abstract method from BasePOMCore
|
|
31
|
+
* Uses theme-specific selectors (THEME_SELECTORS)
|
|
32
|
+
*/
|
|
33
|
+
protected cySelector(path: string, replacements?: Replacements): string {
|
|
34
|
+
return cySelector(path, replacements)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default DashboardEntityPOM
|
|
39
|
+
|
|
40
|
+
// Re-export EntityConfig for convenience
|
|
41
|
+
export type { EntityConfig }
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core POM exports
|
|
3
|
+
*
|
|
4
|
+
* Base classes for building Page Object Models:
|
|
5
|
+
* - BasePOM: Utility methods for all POMs
|
|
6
|
+
* - DashboardEntityPOM: Base for entity CRUD POMs
|
|
7
|
+
* - BlockEditorBasePOM: Base for page/post builder POMs
|
|
8
|
+
* - AuthPOM: Authentication pages POM
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
export { BasePOM } from './BasePOM'
|
|
12
|
+
export { DashboardEntityPOM, type EntityConfig } from './DashboardEntityPOM'
|
|
13
|
+
export { BlockEditorBasePOM } from './BlockEditorBasePOM'
|
|
14
|
+
export { AuthPOM, type SignupData } from './AuthPOM'
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CustomersPOM - Page Object Model for Customers entity
|
|
3
|
+
*
|
|
4
|
+
* Extends DashboardEntityPOM with customer-specific form handling and workflows.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* // Instance usage with chaining
|
|
8
|
+
* CustomersPOM.create()
|
|
9
|
+
* .visitList()
|
|
10
|
+
* .waitForList()
|
|
11
|
+
* .clickAdd()
|
|
12
|
+
* .fillCustomerForm({ name: 'Acme Inc', account: 'ACC001', office: 'HQ' })
|
|
13
|
+
* .submitForm()
|
|
14
|
+
*
|
|
15
|
+
* // API-aware workflow
|
|
16
|
+
* const customers = new CustomersPOM()
|
|
17
|
+
* customers.createCustomerWithApiWait({
|
|
18
|
+
* name: 'Acme Inc',
|
|
19
|
+
* account: 'ACC001',
|
|
20
|
+
* office: 'Main Office'
|
|
21
|
+
* })
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { DashboardEntityPOM } from '../core/DashboardEntityPOM'
|
|
25
|
+
import entitiesConfig from '../../fixtures/entities.json'
|
|
26
|
+
|
|
27
|
+
export interface CustomerFormData {
|
|
28
|
+
name: string
|
|
29
|
+
account: string
|
|
30
|
+
office: string
|
|
31
|
+
phone?: string
|
|
32
|
+
salesRep?: string
|
|
33
|
+
visitDays?: string[]
|
|
34
|
+
contactDays?: string[]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class CustomersPOM extends DashboardEntityPOM {
|
|
38
|
+
constructor() {
|
|
39
|
+
super(entitiesConfig.entities.customers.slug)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ============================================
|
|
43
|
+
// FACTORY METHOD
|
|
44
|
+
// ============================================
|
|
45
|
+
|
|
46
|
+
static create(): CustomersPOM {
|
|
47
|
+
return new CustomersPOM()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ============================================
|
|
51
|
+
// ENTITY-SPECIFIC FORM METHODS
|
|
52
|
+
// ============================================
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Fill customer form with provided data
|
|
56
|
+
* Only fills fields that are provided in the data object
|
|
57
|
+
*/
|
|
58
|
+
fillCustomerForm(data: CustomerFormData) {
|
|
59
|
+
if (data.name) {
|
|
60
|
+
this.fillTextField('name', data.name)
|
|
61
|
+
}
|
|
62
|
+
if (data.account) {
|
|
63
|
+
this.fillTextField('account', data.account)
|
|
64
|
+
}
|
|
65
|
+
if (data.office) {
|
|
66
|
+
this.fillTextField('office', data.office)
|
|
67
|
+
}
|
|
68
|
+
if (data.phone) {
|
|
69
|
+
this.fillTextField('phone', data.phone)
|
|
70
|
+
}
|
|
71
|
+
if (data.salesRep) {
|
|
72
|
+
this.fillTextField('salesRep', data.salesRep)
|
|
73
|
+
}
|
|
74
|
+
return this
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ============================================
|
|
78
|
+
// WORKFLOW METHODS
|
|
79
|
+
// ============================================
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Complete create flow without API waits
|
|
83
|
+
*/
|
|
84
|
+
createCustomer(data: CustomerFormData) {
|
|
85
|
+
this.visitCreate()
|
|
86
|
+
this.waitForForm()
|
|
87
|
+
this.fillCustomerForm(data)
|
|
88
|
+
this.submitForm()
|
|
89
|
+
return this
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Create customer with API intercepts and waits
|
|
94
|
+
* Deterministic: waits for actual API responses
|
|
95
|
+
*/
|
|
96
|
+
createCustomerWithApiWait(data: CustomerFormData) {
|
|
97
|
+
this.setupApiIntercepts()
|
|
98
|
+
this.clickAdd()
|
|
99
|
+
this.waitForForm()
|
|
100
|
+
this.fillCustomerForm(data)
|
|
101
|
+
this.submitForm()
|
|
102
|
+
this.api.waitForCreate()
|
|
103
|
+
return this
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Create customer from list page and wait for refresh
|
|
108
|
+
*/
|
|
109
|
+
createCustomerFromListWithApiWait(data: CustomerFormData) {
|
|
110
|
+
this.setupApiIntercepts()
|
|
111
|
+
this.clickAdd()
|
|
112
|
+
this.waitForForm()
|
|
113
|
+
this.fillCustomerForm(data)
|
|
114
|
+
this.submitForm()
|
|
115
|
+
this.api.waitForCreateAndRefresh()
|
|
116
|
+
return this
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Update customer with API waits
|
|
121
|
+
*/
|
|
122
|
+
updateCustomerWithApiWait(data: Partial<CustomerFormData>) {
|
|
123
|
+
this.fillCustomerForm(data as CustomerFormData)
|
|
124
|
+
this.submitForm()
|
|
125
|
+
this.api.waitForUpdate()
|
|
126
|
+
return this
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Delete customer with API waits
|
|
131
|
+
* Flow: Navigate to detail -> Delete -> Confirm
|
|
132
|
+
*/
|
|
133
|
+
deleteCustomerWithApiWait(id: string) {
|
|
134
|
+
this.visitDetailWithApiWait(id)
|
|
135
|
+
this.clickDelete()
|
|
136
|
+
this.confirmDelete()
|
|
137
|
+
this.api.waitForDelete()
|
|
138
|
+
return this
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Delete customer by finding it in the list by name
|
|
143
|
+
*/
|
|
144
|
+
deleteCustomerByNameWithApiWait(name: string) {
|
|
145
|
+
this.clickRowByText(name)
|
|
146
|
+
this.waitForDetail()
|
|
147
|
+
this.clickDelete()
|
|
148
|
+
this.confirmDelete()
|
|
149
|
+
this.api.waitForDelete()
|
|
150
|
+
return this
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// ============================================
|
|
154
|
+
// ENTITY-SPECIFIC ASSERTIONS
|
|
155
|
+
// ============================================
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Assert customer appears in list
|
|
159
|
+
*/
|
|
160
|
+
assertCustomerInList(name: string) {
|
|
161
|
+
return this.assertInList(name)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Assert customer does not appear in list
|
|
166
|
+
*/
|
|
167
|
+
assertCustomerNotInList(name: string) {
|
|
168
|
+
return this.assertNotInList(name)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export default CustomersPOM
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PagesPOM - Page Object Model for Pages entity (List operations)
|
|
3
|
+
*
|
|
4
|
+
* Extends DashboardEntityPOM for list page operations.
|
|
5
|
+
* For editing pages with the block editor, use PageBuilderPOM from features/.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // List operations
|
|
9
|
+
* PagesPOM.create()
|
|
10
|
+
* .visitList()
|
|
11
|
+
* .waitForList()
|
|
12
|
+
* .search('About Us')
|
|
13
|
+
* .selectFilter('status', 'published')
|
|
14
|
+
*
|
|
15
|
+
* // For editing pages, use PageBuilderPOM
|
|
16
|
+
* import { PageBuilderPOM } from '../features/PageBuilderPOM'
|
|
17
|
+
* PageBuilderPOM.create().visitEdit(pageId).setTitle('New Title').save()
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { DashboardEntityPOM } from '../core/DashboardEntityPOM'
|
|
21
|
+
import entitiesConfig from '../../fixtures/entities.json'
|
|
22
|
+
|
|
23
|
+
export interface PageListFilters {
|
|
24
|
+
status?: 'draft' | 'published' | 'archived'
|
|
25
|
+
locale?: 'en' | 'es'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export class PagesPOM extends DashboardEntityPOM {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(entitiesConfig.entities.pages.slug)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ============================================
|
|
34
|
+
// FACTORY METHOD
|
|
35
|
+
// ============================================
|
|
36
|
+
|
|
37
|
+
static create(): PagesPOM {
|
|
38
|
+
return new PagesPOM()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ============================================
|
|
42
|
+
// PAGE-SPECIFIC LIST METHODS
|
|
43
|
+
// ============================================
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Filter pages by status
|
|
47
|
+
*/
|
|
48
|
+
filterByStatus(status: 'draft' | 'published' | 'archived') {
|
|
49
|
+
return this.selectFilter('status', status)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Apply multiple filters at once
|
|
54
|
+
*/
|
|
55
|
+
applyFilters(filters: PageListFilters) {
|
|
56
|
+
if (filters.status) {
|
|
57
|
+
this.filterByStatus(filters.status)
|
|
58
|
+
}
|
|
59
|
+
if (filters.locale) {
|
|
60
|
+
this.selectFilter('locale', filters.locale)
|
|
61
|
+
}
|
|
62
|
+
return this
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ============================================
|
|
66
|
+
// WORKFLOW METHODS
|
|
67
|
+
// ============================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Navigate to create page
|
|
71
|
+
* Note: Pages use block editor, so this redirects to the editor
|
|
72
|
+
*/
|
|
73
|
+
navigateToCreate() {
|
|
74
|
+
this.clickAdd()
|
|
75
|
+
return this
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Navigate to edit page for a page
|
|
80
|
+
* Note: Pages use block editor, so this redirects to the editor
|
|
81
|
+
*/
|
|
82
|
+
navigateToEdit(id: string) {
|
|
83
|
+
this.clickRowAction('edit', id)
|
|
84
|
+
return this
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Delete page from list with API waits
|
|
89
|
+
*/
|
|
90
|
+
deletePageWithApiWait(id: string) {
|
|
91
|
+
this.visitDetailWithApiWait(id)
|
|
92
|
+
this.clickDelete()
|
|
93
|
+
this.confirmDelete()
|
|
94
|
+
this.api.waitForDelete()
|
|
95
|
+
return this
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Delete page by finding it in the list by title
|
|
100
|
+
*/
|
|
101
|
+
deletePageByTitleWithApiWait(title: string) {
|
|
102
|
+
this.clickRowByText(title)
|
|
103
|
+
this.waitForDetail()
|
|
104
|
+
this.clickDelete()
|
|
105
|
+
this.confirmDelete()
|
|
106
|
+
this.api.waitForDelete()
|
|
107
|
+
return this
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ============================================
|
|
111
|
+
// ENTITY-SPECIFIC ASSERTIONS
|
|
112
|
+
// ============================================
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Assert page appears in list
|
|
116
|
+
*/
|
|
117
|
+
assertPageInList(title: string) {
|
|
118
|
+
return this.assertInList(title)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Assert page does not appear in list
|
|
123
|
+
*/
|
|
124
|
+
assertPageNotInList(title: string) {
|
|
125
|
+
return this.assertNotInList(title)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Assert page has specific status badge
|
|
130
|
+
*/
|
|
131
|
+
assertPageStatus(id: string, status: string) {
|
|
132
|
+
cy.get(this.selectors.row(id)).should('contain.text', status)
|
|
133
|
+
return this
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default PagesPOM
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PatternsPOM - Page Object Model for Patterns entity
|
|
3
|
+
*
|
|
4
|
+
* Extends DashboardEntityPOM for standard CRUD operations on patterns.
|
|
5
|
+
* Includes pattern-specific methods for:
|
|
6
|
+
* - Usage report interactions
|
|
7
|
+
* - Delete dialog with usage checking
|
|
8
|
+
* - Placeholder handling in block editor
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // List operations
|
|
12
|
+
* PatternsPOM.create()
|
|
13
|
+
* .visitList()
|
|
14
|
+
* .waitForList()
|
|
15
|
+
* .search('Hero Section')
|
|
16
|
+
*
|
|
17
|
+
* // View pattern usage
|
|
18
|
+
* PatternsPOM.create()
|
|
19
|
+
* .visitDetailWithApiWait(patternId)
|
|
20
|
+
* .assertUsageStatsLoaded()
|
|
21
|
+
*
|
|
22
|
+
* // Delete with usage warning (from list)
|
|
23
|
+
* PatternsPOM.create()
|
|
24
|
+
* .visitList()
|
|
25
|
+
* .openDeleteDialogFromList(patternId)
|
|
26
|
+
* .assertUsageWarningVisible()
|
|
27
|
+
* .confirmPatternDelete()
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import { DashboardEntityPOM } from '../core/DashboardEntityPOM'
|
|
31
|
+
import { cySelector } from '../selectors'
|
|
32
|
+
import entitiesConfig from '../../fixtures/entities.json'
|
|
33
|
+
|
|
34
|
+
export class PatternsPOM extends DashboardEntityPOM {
|
|
35
|
+
constructor() {
|
|
36
|
+
super(entitiesConfig.entities.patterns.slug)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ============================================
|
|
40
|
+
// FACTORY METHOD
|
|
41
|
+
// ============================================
|
|
42
|
+
|
|
43
|
+
static create(): PatternsPOM {
|
|
44
|
+
return new PatternsPOM()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ============================================
|
|
48
|
+
// PATTERN-SPECIFIC SELECTORS
|
|
49
|
+
// ============================================
|
|
50
|
+
|
|
51
|
+
get patternSelectors() {
|
|
52
|
+
return {
|
|
53
|
+
// Usage Table
|
|
54
|
+
usageTable: {
|
|
55
|
+
container: cySelector('patterns.usageTable.container'),
|
|
56
|
+
loading: cySelector('patterns.usageTable.loading'),
|
|
57
|
+
empty: cySelector('patterns.usageTable.empty'),
|
|
58
|
+
row: (id: string) => cySelector('patterns.usageTable.row', { id }),
|
|
59
|
+
viewLink: (id: string) => cySelector('patterns.usageTable.viewLink', { id }),
|
|
60
|
+
},
|
|
61
|
+
// Usage Stats
|
|
62
|
+
usageStats: {
|
|
63
|
+
container: cySelector('patterns.usageStats.container'),
|
|
64
|
+
loading: cySelector('patterns.usageStats.loading'),
|
|
65
|
+
total: cySelector('patterns.usageStats.total'),
|
|
66
|
+
byType: (entityType: string) => cySelector('patterns.usageStats.byType', { entityType }),
|
|
67
|
+
},
|
|
68
|
+
// Usage Report
|
|
69
|
+
usageReport: {
|
|
70
|
+
container: cySelector('patterns.usageReport.container'),
|
|
71
|
+
error: cySelector('patterns.usageReport.error'),
|
|
72
|
+
filters: cySelector('patterns.usageReport.filters'),
|
|
73
|
+
filterSelect: cySelector('patterns.usageReport.filterSelect'),
|
|
74
|
+
pagination: cySelector('patterns.usageReport.pagination'),
|
|
75
|
+
prevPage: cySelector('patterns.usageReport.prevPage'),
|
|
76
|
+
nextPage: cySelector('patterns.usageReport.nextPage'),
|
|
77
|
+
resultsInfo: cySelector('patterns.usageReport.resultsInfo'),
|
|
78
|
+
},
|
|
79
|
+
// Delete Dialog
|
|
80
|
+
deleteDialog: {
|
|
81
|
+
trigger: cySelector('patterns.deleteDialog.trigger'),
|
|
82
|
+
container: cySelector('patterns.deleteDialog.container'),
|
|
83
|
+
loading: cySelector('patterns.deleteDialog.loading'),
|
|
84
|
+
error: cySelector('patterns.deleteDialog.error'),
|
|
85
|
+
warning: cySelector('patterns.deleteDialog.warning'),
|
|
86
|
+
usageList: cySelector('patterns.deleteDialog.usageList'),
|
|
87
|
+
noUsage: cySelector('patterns.deleteDialog.noUsage'),
|
|
88
|
+
cancel: cySelector('patterns.deleteDialog.cancel'),
|
|
89
|
+
confirm: cySelector('patterns.deleteDialog.confirm'),
|
|
90
|
+
},
|
|
91
|
+
// Deleted Pattern Placeholder
|
|
92
|
+
placeholder: {
|
|
93
|
+
container: cySelector('patterns.placeholder.container'),
|
|
94
|
+
removeBtn: cySelector('patterns.placeholder.removeBtn'),
|
|
95
|
+
},
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ============================================
|
|
100
|
+
// USAGE REPORT METHODS
|
|
101
|
+
// ============================================
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Assert usage stats container is visible and loaded
|
|
105
|
+
*/
|
|
106
|
+
assertUsageStatsLoaded(): this {
|
|
107
|
+
cy.get(this.patternSelectors.usageStats.container).should('be.visible')
|
|
108
|
+
cy.get(this.patternSelectors.usageStats.loading).should('not.exist')
|
|
109
|
+
return this
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Assert usage table is visible and loaded
|
|
114
|
+
*/
|
|
115
|
+
assertUsageTableLoaded(): this {
|
|
116
|
+
cy.get(this.patternSelectors.usageTable.container).should('be.visible')
|
|
117
|
+
cy.get(this.patternSelectors.usageTable.loading).should('not.exist')
|
|
118
|
+
return this
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Assert usage report shows empty state
|
|
123
|
+
*/
|
|
124
|
+
assertUsageTableEmpty(): this {
|
|
125
|
+
cy.get(this.patternSelectors.usageTable.empty).should('be.visible')
|
|
126
|
+
return this
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Assert total usage count
|
|
131
|
+
*/
|
|
132
|
+
assertTotalUsageCount(expectedCount: number): this {
|
|
133
|
+
cy.get(this.patternSelectors.usageStats.total)
|
|
134
|
+
.should('contain.text', expectedCount.toString())
|
|
135
|
+
return this
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Filter usage by entity type
|
|
140
|
+
*/
|
|
141
|
+
filterUsageByType(entityType: string): this {
|
|
142
|
+
cy.get(this.patternSelectors.usageReport.filterSelect).click()
|
|
143
|
+
cy.get(`[data-value="${entityType}"]`).click()
|
|
144
|
+
return this
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Navigate to next page of usage results
|
|
149
|
+
*/
|
|
150
|
+
goToNextUsagePage(): this {
|
|
151
|
+
cy.get(this.patternSelectors.usageReport.nextPage).click()
|
|
152
|
+
return this
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Navigate to previous page of usage results
|
|
157
|
+
*/
|
|
158
|
+
goToPrevUsagePage(): this {
|
|
159
|
+
cy.get(this.patternSelectors.usageReport.prevPage).click()
|
|
160
|
+
return this
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Click view link for a specific usage row
|
|
165
|
+
*/
|
|
166
|
+
clickUsageViewLink(usageId: string): this {
|
|
167
|
+
cy.get(this.patternSelectors.usageTable.viewLink(usageId)).click()
|
|
168
|
+
return this
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ============================================
|
|
172
|
+
// DELETE DIALOG METHODS
|
|
173
|
+
// ============================================
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Open the delete dialog for a pattern from the list dropdown menu
|
|
177
|
+
* @param id - The pattern ID to delete
|
|
178
|
+
*/
|
|
179
|
+
openDeleteDialogFromList(id: string): this {
|
|
180
|
+
// Click on the dropdown menu first
|
|
181
|
+
cy.get(this.selectors.rowMenu(id)).click()
|
|
182
|
+
// Then click the delete action
|
|
183
|
+
cy.get(this.selectors.rowAction('delete', id)).click()
|
|
184
|
+
// Wait for dialog to be visible
|
|
185
|
+
cy.get(this.patternSelectors.deleteDialog.container).should('be.visible')
|
|
186
|
+
return this
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Open the delete dialog using the standalone trigger (if present)
|
|
191
|
+
* @deprecated Use openDeleteDialogFromList() for list-based deletion
|
|
192
|
+
*/
|
|
193
|
+
openDeleteDialog(): this {
|
|
194
|
+
cy.get(this.patternSelectors.deleteDialog.trigger).click()
|
|
195
|
+
cy.get(this.patternSelectors.deleteDialog.container).should('be.visible')
|
|
196
|
+
return this
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Wait for usage check to complete in delete dialog
|
|
201
|
+
*/
|
|
202
|
+
waitForUsageCheck(): this {
|
|
203
|
+
cy.get(this.patternSelectors.deleteDialog.loading).should('not.exist')
|
|
204
|
+
return this
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Assert the delete dialog shows usage warning
|
|
209
|
+
*/
|
|
210
|
+
assertUsageWarningVisible(): this {
|
|
211
|
+
cy.get(this.patternSelectors.deleteDialog.warning).should('be.visible')
|
|
212
|
+
return this
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Assert the delete dialog shows no usage message
|
|
217
|
+
*/
|
|
218
|
+
assertNoUsageVisible(): this {
|
|
219
|
+
cy.get(this.patternSelectors.deleteDialog.noUsage).should('be.visible')
|
|
220
|
+
return this
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Assert the delete dialog shows error
|
|
225
|
+
*/
|
|
226
|
+
assertDeleteDialogError(): this {
|
|
227
|
+
cy.get(this.patternSelectors.deleteDialog.error).should('be.visible')
|
|
228
|
+
return this
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Confirm deletion in the delete dialog
|
|
233
|
+
*/
|
|
234
|
+
confirmPatternDelete(): this {
|
|
235
|
+
cy.get(this.patternSelectors.deleteDialog.confirm).click()
|
|
236
|
+
return this
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Cancel deletion in the delete dialog
|
|
241
|
+
*/
|
|
242
|
+
cancelPatternDelete(): this {
|
|
243
|
+
cy.get(this.patternSelectors.deleteDialog.cancel).click()
|
|
244
|
+
return this
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Delete pattern from list with API wait
|
|
249
|
+
* Handles the full flow: open dialog from dropdown, wait for usage check, confirm
|
|
250
|
+
* @param id - The pattern ID to delete
|
|
251
|
+
*/
|
|
252
|
+
deletePatternFromListWithApiWait(id: string): this {
|
|
253
|
+
this.openDeleteDialogFromList(id)
|
|
254
|
+
this.waitForUsageCheck()
|
|
255
|
+
this.api.interceptDelete()
|
|
256
|
+
this.confirmPatternDelete()
|
|
257
|
+
this.api.waitForDelete()
|
|
258
|
+
return this
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Delete pattern with API wait (using standalone trigger)
|
|
263
|
+
* @deprecated Use deletePatternFromListWithApiWait() for list-based deletion
|
|
264
|
+
*/
|
|
265
|
+
deletePatternWithApiWait(): this {
|
|
266
|
+
this.openDeleteDialog()
|
|
267
|
+
this.waitForUsageCheck()
|
|
268
|
+
this.api.interceptDelete()
|
|
269
|
+
this.confirmPatternDelete()
|
|
270
|
+
this.api.waitForDelete()
|
|
271
|
+
return this
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// ============================================
|
|
275
|
+
// PLACEHOLDER METHODS (Block Editor context)
|
|
276
|
+
// ============================================
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Assert deleted pattern placeholder is visible
|
|
280
|
+
*/
|
|
281
|
+
assertPlaceholderVisible(): this {
|
|
282
|
+
cy.get(this.patternSelectors.placeholder.container).should('be.visible')
|
|
283
|
+
return this
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Click remove button on deleted pattern placeholder
|
|
288
|
+
*/
|
|
289
|
+
clickPlaceholderRemove(): this {
|
|
290
|
+
cy.get(this.patternSelectors.placeholder.removeBtn).click()
|
|
291
|
+
return this
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// ============================================
|
|
295
|
+
// WORKFLOW METHODS
|
|
296
|
+
// ============================================
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Create a new pattern (navigates to create page)
|
|
300
|
+
*/
|
|
301
|
+
navigateToCreate(): this {
|
|
302
|
+
this.clickAdd()
|
|
303
|
+
return this
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Navigate to edit a pattern
|
|
308
|
+
*/
|
|
309
|
+
navigateToEdit(id: string): this {
|
|
310
|
+
this.clickRowAction('edit', id)
|
|
311
|
+
return this
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Assert pattern appears in list
|
|
316
|
+
*/
|
|
317
|
+
assertPatternInList(title: string): this {
|
|
318
|
+
return this.assertInList(title)
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Assert pattern does not appear in list
|
|
323
|
+
*/
|
|
324
|
+
assertPatternNotInList(title: string): this {
|
|
325
|
+
return this.assertNotInList(title)
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export default PatternsPOM
|