@nextsparkjs/theme-default 0.1.0-beta.20 → 0.1.0-beta.21
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/package.json +1 -1
- package/tests/cypress/e2e/_devtools/access.bdd.md +262 -0
- package/tests/cypress/e2e/_devtools/access.cy.ts +171 -0
- package/tests/cypress/e2e/_devtools/navigation.bdd.md +261 -0
- package/tests/cypress/e2e/_devtools/navigation.cy.ts +157 -0
- package/tests/cypress/e2e/_devtools/pages.bdd.md +303 -0
- package/tests/cypress/e2e/_devtools/pages.cy.ts +184 -0
- package/tests/cypress/e2e/_docs/README.md +215 -0
- package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin-teams.narration.json +155 -0
- package/tests/cypress/e2e/_docs/tutorials/sector7-superadmin.cy.ts +390 -0
- package/tests/cypress/e2e/_docs/tutorials/teams-system.doc.cy.ts +349 -0
- package/tests/cypress/e2e/_docs/tutorials/teams-system.narration.json +165 -0
- package/tests/cypress/e2e/_selectors/auth.cy.ts +306 -0
- package/tests/cypress/e2e/_selectors/billing.cy.ts +89 -0
- package/tests/cypress/e2e/_selectors/dashboard-mobile.cy.ts +113 -0
- package/tests/cypress/e2e/_selectors/dashboard-navigation.cy.ts +89 -0
- package/tests/cypress/e2e/_selectors/dashboard-sidebar.cy.ts +60 -0
- package/tests/cypress/e2e/_selectors/dashboard-topnav.cy.ts +146 -0
- package/tests/cypress/e2e/_selectors/devtools.cy.ts +210 -0
- package/tests/cypress/e2e/_selectors/global-search.cy.ts +88 -0
- package/tests/cypress/e2e/_selectors/pages-editor.cy.ts +179 -0
- package/tests/cypress/e2e/_selectors/posts-editor.cy.ts +282 -0
- package/tests/cypress/e2e/_selectors/public.cy.ts +112 -0
- package/tests/cypress/e2e/_selectors/settings-api-keys.cy.ts +228 -0
- package/tests/cypress/e2e/_selectors/settings-billing.cy.ts +105 -0
- package/tests/cypress/e2e/_selectors/settings-layout.cy.ts +119 -0
- package/tests/cypress/e2e/_selectors/settings-password.cy.ts +71 -0
- package/tests/cypress/e2e/_selectors/settings-profile.cy.ts +82 -0
- package/tests/cypress/e2e/_selectors/settings-teams.cy.ts +68 -0
- package/tests/cypress/e2e/_selectors/superadmin.cy.ts +185 -0
- package/tests/cypress/e2e/_selectors/tasks.cy.ts +242 -0
- package/tests/cypress/e2e/_selectors/taxonomies.cy.ts +126 -0
- package/tests/cypress/e2e/_selectors/teams.cy.ts +142 -0
- package/tests/cypress/e2e/_superadmin/all-teams.bdd.md +261 -0
- package/tests/cypress/e2e/_superadmin/all-teams.cy.ts +177 -0
- package/tests/cypress/e2e/_superadmin/all-users.bdd.md +406 -0
- package/tests/cypress/e2e/_superadmin/all-users.cy.ts +294 -0
- package/tests/cypress/e2e/_superadmin/dashboard.bdd.md +235 -0
- package/tests/cypress/e2e/_superadmin/dashboard.cy.ts +149 -0
- package/tests/cypress/e2e/_superadmin/subscriptions-overview.bdd.md +290 -0
- package/tests/cypress/e2e/_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 +107 -0
- package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
- package/tests/cypress/e2e/api/billing/BillingAPIController.js +319 -0
- package/tests/cypress/e2e/api/billing/check-action.cy.ts +326 -0
- package/tests/cypress/e2e/api/billing/checkout.cy.ts +358 -0
- package/tests/cypress/e2e/api/billing/lifecycle.cy.ts +423 -0
- package/tests/cypress/e2e/api/billing/plans/README.md +345 -0
- package/tests/cypress/e2e/api/billing/plans/business.cy.ts +412 -0
- package/tests/cypress/e2e/api/billing/plans/downgrade.cy.ts +510 -0
- package/tests/cypress/e2e/api/billing/plans/fixtures/billing-plans.json +163 -0
- package/tests/cypress/e2e/api/billing/plans/free.cy.ts +500 -0
- package/tests/cypress/e2e/api/billing/plans/pro.cy.ts +497 -0
- package/tests/cypress/e2e/api/billing/plans/starter.cy.ts +342 -0
- package/tests/cypress/e2e/api/billing/portal.cy.ts +313 -0
- package/tests/cypress/e2e/api/devtools/registries.bdd.md +300 -0
- package/tests/cypress/e2e/api/devtools/registries.cy.ts +368 -0
- package/tests/cypress/e2e/api/entities/blocks-scope.cy.ts +396 -0
- package/tests/cypress/e2e/api/entities/customers-crud.cy.ts +648 -0
- package/tests/cypress/e2e/api/entities/customers-metas.cy.ts +839 -0
- package/tests/cypress/e2e/api/entities/pages-crud.cy.ts +425 -0
- package/tests/cypress/e2e/api/entities/pages-status.cy.ts +335 -0
- package/tests/cypress/e2e/api/entities/post-categories-crud.cy.ts +610 -0
- package/tests/cypress/e2e/api/entities/posts-crud.cy.ts +709 -0
- package/tests/cypress/e2e/api/entities/posts-status.cy.ts +396 -0
- package/tests/cypress/e2e/api/entities/tasks-crud.cy.ts +602 -0
- package/tests/cypress/e2e/api/entities/tasks-metas.cy.ts +878 -0
- package/tests/cypress/e2e/api/entities/users-crud.cy.ts +469 -0
- package/tests/cypress/e2e/api/entities/users-metas.cy.ts +913 -0
- package/tests/cypress/e2e/api/entities/users-security.cy.ts +375 -0
- package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.bdd.md +375 -0
- package/tests/cypress/e2e/api/scheduled-actions/cron-endpoint.cy.ts +346 -0
- package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.bdd.md +451 -0
- package/tests/cypress/e2e/api/scheduled-actions/devtools-endpoint.cy.ts +447 -0
- package/tests/cypress/e2e/api/scheduled-actions/scheduling.bdd.md +649 -0
- package/tests/cypress/e2e/api/scheduled-actions/scheduling.cy.ts +333 -0
- package/tests/cypress/e2e/api/settings/api-keys.crud.cy.ts +923 -0
- package/tests/cypress/e2e/uat/auth/app-roles/developer-login.bdd.md +231 -0
- package/tests/cypress/e2e/uat/auth/app-roles/developer-login.cy.ts +144 -0
- package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.bdd.md +118 -0
- package/tests/cypress/e2e/uat/auth/app-roles/superadmin-login.cy.ts +84 -0
- package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.bdd.md +288 -0
- package/tests/cypress/e2e/uat/auth/custom-roles/editor-login.cy.ts +188 -0
- package/tests/cypress/e2e/uat/auth/login-logout.bdd.md +160 -0
- package/tests/cypress/e2e/uat/auth/login-logout.cy.ts +116 -0
- package/tests/cypress/e2e/uat/auth/password-reset.bdd.md +289 -0
- package/tests/cypress/e2e/uat/auth/password-reset.cy.ts +200 -0
- package/tests/cypress/e2e/uat/auth/team-roles/admin-login.bdd.md +225 -0
- package/tests/cypress/e2e/uat/auth/team-roles/admin-login.cy.ts +148 -0
- package/tests/cypress/e2e/uat/auth/team-roles/member-login.bdd.md +251 -0
- package/tests/cypress/e2e/uat/auth/team-roles/member-login.cy.ts +163 -0
- package/tests/cypress/e2e/uat/auth/team-roles/owner-login.bdd.md +231 -0
- package/tests/cypress/e2e/uat/auth/team-roles/owner-login.cy.ts +141 -0
- package/tests/cypress/e2e/uat/billing/extended.bdd.md +273 -0
- package/tests/cypress/e2e/uat/billing/extended.cy.ts +209 -0
- package/tests/cypress/e2e/uat/billing/feature-gates.bdd.md +407 -0
- package/tests/cypress/e2e/uat/billing/feature-gates.cy.ts +307 -0
- package/tests/cypress/e2e/uat/billing/page.bdd.md +329 -0
- package/tests/cypress/e2e/uat/billing/page.cy.ts +250 -0
- package/tests/cypress/e2e/uat/billing/status.bdd.md +190 -0
- package/tests/cypress/e2e/uat/billing/status.cy.ts +145 -0
- package/tests/cypress/e2e/uat/billing/team-switch.bdd.md +156 -0
- package/tests/cypress/e2e/uat/billing/team-switch.cy.ts +122 -0
- package/tests/cypress/e2e/uat/billing/usage.bdd.md +218 -0
- package/tests/cypress/e2e/uat/billing/usage.cy.ts +176 -0
- package/tests/cypress/e2e/uat/blocks/hero.bdd.md +124 -0
- package/tests/cypress/e2e/uat/blocks/hero.cy.ts +56 -0
- package/tests/cypress/e2e/uat/devtools/api-tester.cy.ts +390 -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/roles/editor-role.bdd.md +552 -0
- package/tests/cypress/e2e/uat/roles/editor-role.cy.ts +210 -0
- package/tests/cypress/e2e/uat/roles/member-restrictions.bdd.md +450 -0
- package/tests/cypress/e2e/uat/roles/member-restrictions.cy.ts +189 -0
- package/tests/cypress/e2e/uat/roles/owner-full-crud.bdd.md +530 -0
- package/tests/cypress/e2e/uat/roles/owner-full-crud.cy.ts +247 -0
- package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.bdd.md +736 -0
- package/tests/cypress/e2e/uat/scheduled-actions/devtools-ui.cy.ts +740 -0
- package/tests/cypress/e2e/uat/teams/roles-matrix.bdd.md +553 -0
- package/tests/cypress/e2e/uat/teams/roles-matrix.cy.ts +185 -0
- package/tests/cypress/e2e/uat/teams/switcher.bdd.md +1151 -0
- package/tests/cypress/e2e/uat/teams/switcher.cy.ts +497 -0
- package/tests/cypress/e2e/uat/teams/team-switcher.md +198 -0
- package/tests/cypress/fixtures/blocks.json +218 -0
- package/tests/cypress/fixtures/entities.json +78 -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/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 +86 -0
- package/tests/cypress/src/core/BlockEditorBasePOM.ts +576 -0
- package/tests/cypress/src/core/DashboardEntityPOM.ts +692 -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/PostsPOM.ts +137 -0
- package/tests/cypress/src/entities/TasksPOM.ts +176 -0
- package/tests/cypress/src/entities/index.ts +14 -0
- package/tests/cypress/src/features/BillingPOM.ts +385 -0
- package/tests/cypress/src/features/DashboardPOM.ts +245 -0
- package/tests/cypress/src/features/DevtoolsPOM.ts +739 -0
- package/tests/cypress/src/features/PageBuilderPOM.ts +263 -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 +362 -0
- package/tests/cypress/src/features/SuperadminPOM.ts +331 -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 +177 -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 +500 -0
- package/tests/cypress/support/doc-commands.ts +260 -0
- package/tests/cypress.config.ts +150 -0
- package/tests/jest/components/post-header.test.tsx +377 -0
- package/tests/jest/config/role-config.test.ts +529 -0
- package/tests/jest/jest.config.ts +81 -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 +367 -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/user-roles/role-helpers.test.ts +432 -0
- package/tests/jest/validation/categories.test.ts +429 -0
- package/tests/jest/validation/posts.test.ts +546 -0
- package/tests/tsconfig.json +15 -0
|
@@ -0,0 +1,692 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DashboardEntityPOM - Base class for all entity Page Object Models
|
|
3
|
+
*
|
|
4
|
+
* Provides standard CRUD operations for dashboard entities:
|
|
5
|
+
* - Navigation (list, create, edit, detail pages)
|
|
6
|
+
* - Table interactions (search, filters, pagination, row actions)
|
|
7
|
+
* - Form operations (fill fields, submit, cancel)
|
|
8
|
+
* - API interceptor integration for deterministic waits
|
|
9
|
+
* - Bulk actions
|
|
10
|
+
* - Delete confirmation dialogs
|
|
11
|
+
*
|
|
12
|
+
* Entity POMs should extend this class and add entity-specific methods.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* class TasksPOM extends DashboardEntityPOM {
|
|
16
|
+
* constructor() {
|
|
17
|
+
* super('tasks')
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* fillTaskForm(data: TaskFormData) {
|
|
21
|
+
* // Entity-specific form handling
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { BasePOM } from './BasePOM'
|
|
27
|
+
import { cySelector } from '../selectors'
|
|
28
|
+
import entitiesConfig from '../../fixtures/entities.json'
|
|
29
|
+
import { ApiInterceptor } from '../helpers/ApiInterceptor'
|
|
30
|
+
|
|
31
|
+
export interface EntityConfig {
|
|
32
|
+
slug: string
|
|
33
|
+
singular: string
|
|
34
|
+
plural: string
|
|
35
|
+
tableName: string
|
|
36
|
+
fields: string[]
|
|
37
|
+
filters: string[]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export abstract class DashboardEntityPOM extends BasePOM {
|
|
41
|
+
protected slug: string
|
|
42
|
+
protected entityConfig: EntityConfig
|
|
43
|
+
protected _api: ApiInterceptor | null = null
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get the entity slug (public accessor)
|
|
47
|
+
* Useful for building dynamic selectors and URLs in tests
|
|
48
|
+
*/
|
|
49
|
+
get entitySlug(): string {
|
|
50
|
+
return this.slug
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
constructor(entitySlug: string) {
|
|
54
|
+
super()
|
|
55
|
+
// Find entity config by slug
|
|
56
|
+
const entry = Object.entries(entitiesConfig.entities).find(([, config]) => config.slug === entitySlug)
|
|
57
|
+
if (!entry) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`Unknown entity slug: ${entitySlug}. Available: ${Object.values(entitiesConfig.entities).map(e => e.slug).join(', ')}`
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
this.entityConfig = entry[1] as EntityConfig
|
|
63
|
+
this.slug = entitySlug
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ============================================
|
|
67
|
+
// API INTERCEPTOR
|
|
68
|
+
// ============================================
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get or create ApiInterceptor instance for this entity
|
|
72
|
+
*/
|
|
73
|
+
get api(): ApiInterceptor {
|
|
74
|
+
if (!this._api) {
|
|
75
|
+
this._api = new ApiInterceptor(this.slug)
|
|
76
|
+
}
|
|
77
|
+
return this._api
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Setup API intercepts for all CRUD operations
|
|
82
|
+
* Call this BEFORE navigation
|
|
83
|
+
*/
|
|
84
|
+
setupApiIntercepts() {
|
|
85
|
+
this.api.setupCrudIntercepts()
|
|
86
|
+
return this
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ============================================
|
|
90
|
+
// SELECTORS (from centralized selectors.ts)
|
|
91
|
+
// ============================================
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get all selectors for this entity, with placeholders replaced
|
|
95
|
+
*/
|
|
96
|
+
get selectors() {
|
|
97
|
+
const slug = this.slug
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
// Page
|
|
101
|
+
page: cySelector('entities.page.container', { slug }),
|
|
102
|
+
pageTitle: cySelector('entities.page.title', { slug }),
|
|
103
|
+
|
|
104
|
+
// Table
|
|
105
|
+
tableContainer: cySelector('entities.table.container', { slug }),
|
|
106
|
+
table: cySelector('entities.table.element', { slug }),
|
|
107
|
+
addButton: cySelector('entities.table.addButton', { slug }),
|
|
108
|
+
search: cySelector('entities.search.input', { slug }),
|
|
109
|
+
searchContainer: cySelector('entities.search.container', { slug }),
|
|
110
|
+
searchClear: cySelector('entities.search.clear', { slug }),
|
|
111
|
+
selectAll: cySelector('entities.table.selectAll', { slug }),
|
|
112
|
+
selectionCount: cySelector('entities.table.selectionCount', { slug }),
|
|
113
|
+
row: (id: string) => cySelector('entities.table.row', { slug, id }),
|
|
114
|
+
rowSelect: (id: string) => cySelector('entities.table.rowSelect', { slug, id }),
|
|
115
|
+
rowMenu: (id: string) => cySelector('entities.table.rowMenu', { slug, id }),
|
|
116
|
+
rowAction: (action: string, id: string) => cySelector('entities.table.rowAction', { slug, action, id }),
|
|
117
|
+
cell: (field: string, id: string) => cySelector('entities.table.cell', { slug, field, id }),
|
|
118
|
+
rowGeneric: `[data-cy^="${slug}-row-"]`,
|
|
119
|
+
|
|
120
|
+
// Pagination
|
|
121
|
+
pagination: cySelector('entities.pagination.container', { slug }),
|
|
122
|
+
pageSize: cySelector('entities.pagination.pageSize', { slug }),
|
|
123
|
+
pageSizeOption: (size: string) => cySelector('entities.pagination.pageSizeOption', { slug, size }),
|
|
124
|
+
pageInfo: cySelector('entities.pagination.pageInfo', { slug }),
|
|
125
|
+
pageFirst: cySelector('entities.pagination.first', { slug }),
|
|
126
|
+
pagePrev: cySelector('entities.pagination.prev', { slug }),
|
|
127
|
+
pageNext: cySelector('entities.pagination.next', { slug }),
|
|
128
|
+
pageLast: cySelector('entities.pagination.last', { slug }),
|
|
129
|
+
|
|
130
|
+
// Header (detail pages) - modes: view, edit, create
|
|
131
|
+
viewHeader: cySelector('entities.header.container', { slug, mode: 'view' }),
|
|
132
|
+
editHeader: cySelector('entities.header.container', { slug, mode: 'edit' }),
|
|
133
|
+
createHeader: cySelector('entities.header.container', { slug, mode: 'create' }),
|
|
134
|
+
backButton: cySelector('entities.header.backButton', { slug }),
|
|
135
|
+
editButton: cySelector('entities.header.editButton', { slug }),
|
|
136
|
+
deleteButton: cySelector('entities.header.deleteButton', { slug }),
|
|
137
|
+
copyId: cySelector('entities.header.copyId', { slug }),
|
|
138
|
+
title: cySelector('entities.header.title', { slug }),
|
|
139
|
+
|
|
140
|
+
// Delete confirmation
|
|
141
|
+
deleteDialog: cySelector('entities.header.deleteDialog', { slug }),
|
|
142
|
+
deleteCancel: cySelector('entities.header.deleteCancel', { slug }),
|
|
143
|
+
deleteConfirm: cySelector('entities.header.deleteConfirm', { slug }),
|
|
144
|
+
|
|
145
|
+
// Form
|
|
146
|
+
form: cySelector('entities.form.container', { slug }),
|
|
147
|
+
field: (name: string) => cySelector('entities.form.field', { slug, name }),
|
|
148
|
+
submitButton: cySelector('entities.form.submitButton', { slug }),
|
|
149
|
+
|
|
150
|
+
// Filters
|
|
151
|
+
filter: (field: string) => cySelector('entities.filter.container', { slug, field }),
|
|
152
|
+
filterTrigger: (field: string) => cySelector('entities.filter.trigger', { slug, field }),
|
|
153
|
+
filterContent: (field: string) => cySelector('entities.filter.content', { slug, field }),
|
|
154
|
+
filterOption: (field: string, value: string) => cySelector('entities.filter.option', { slug, field, value }),
|
|
155
|
+
filterBadge: (field: string, value: string) => cySelector('entities.filter.badge', { slug, field, value }),
|
|
156
|
+
filterRemoveBadge: (field: string, value: string) =>
|
|
157
|
+
cySelector('entities.filter.removeBadge', { slug, field, value }),
|
|
158
|
+
filterClearAll: (field: string) => cySelector('entities.filter.clearAll', { slug, field }),
|
|
159
|
+
|
|
160
|
+
// Bulk actions
|
|
161
|
+
bulkBar: cySelector('entities.bulk.bar', { slug }),
|
|
162
|
+
bulkCount: cySelector('entities.bulk.count', { slug }),
|
|
163
|
+
bulkSelectAll: cySelector('entities.bulk.selectAll', { slug }),
|
|
164
|
+
bulkStatus: cySelector('entities.bulk.statusButton', { slug }),
|
|
165
|
+
bulkDelete: cySelector('entities.bulk.deleteButton', { slug }),
|
|
166
|
+
bulkClear: cySelector('entities.bulk.clearButton', { slug }),
|
|
167
|
+
|
|
168
|
+
// Bulk status dialog
|
|
169
|
+
bulkStatusDialog: cySelector('entities.bulk.statusDialog', { slug }),
|
|
170
|
+
bulkStatusSelect: cySelector('entities.bulk.statusSelect', { slug }),
|
|
171
|
+
bulkStatusOption: (value: string) => cySelector('entities.bulk.statusOption', { slug, value }),
|
|
172
|
+
bulkStatusCancel: cySelector('entities.bulk.statusCancel', { slug }),
|
|
173
|
+
bulkStatusConfirm: cySelector('entities.bulk.statusConfirm', { slug }),
|
|
174
|
+
|
|
175
|
+
// Bulk delete dialog
|
|
176
|
+
bulkDeleteDialog: cySelector('entities.bulk.deleteDialog', { slug }),
|
|
177
|
+
bulkDeleteCancel: cySelector('entities.bulk.deleteCancel', { slug }),
|
|
178
|
+
bulkDeleteConfirm: cySelector('entities.bulk.deleteConfirm', { slug }),
|
|
179
|
+
|
|
180
|
+
// Generic confirm dialog
|
|
181
|
+
confirmDialog: cySelector('entities.confirm.dialog', { slug }),
|
|
182
|
+
confirmCancel: cySelector('entities.confirm.cancel', { slug }),
|
|
183
|
+
confirmAction: cySelector('entities.confirm.action', { slug }),
|
|
184
|
+
|
|
185
|
+
// Parent delete confirmation (EntityDetailWrapper - generic, no slug)
|
|
186
|
+
parentDeleteConfirm: '[data-cy="confirm-delete"]',
|
|
187
|
+
parentDeleteCancel: '[data-cy="cancel-delete"]',
|
|
188
|
+
|
|
189
|
+
// Row action selectors (generic patterns for checking existence)
|
|
190
|
+
rowActionEditGeneric: `[data-cy^="${slug}-action-edit-"]`,
|
|
191
|
+
rowActionDeleteGeneric: `[data-cy^="${slug}-action-delete-"]`,
|
|
192
|
+
|
|
193
|
+
// Detail view
|
|
194
|
+
detail: cySelector('entities.detail.container', { slug })
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// ============================================
|
|
199
|
+
// NAVIGATION
|
|
200
|
+
// ============================================
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Navigate to entity list page
|
|
204
|
+
*/
|
|
205
|
+
visitList() {
|
|
206
|
+
cy.visit(`/dashboard/${this.slug}`)
|
|
207
|
+
return this
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Navigate to create page
|
|
212
|
+
*/
|
|
213
|
+
visitCreate() {
|
|
214
|
+
cy.visit(`/dashboard/${this.slug}/create`)
|
|
215
|
+
return this
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Navigate to edit page for specific entity
|
|
220
|
+
*/
|
|
221
|
+
visitEdit(id: string) {
|
|
222
|
+
cy.visit(`/dashboard/${this.slug}/${id}/edit`)
|
|
223
|
+
return this
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Navigate to detail/view page for specific entity
|
|
228
|
+
*/
|
|
229
|
+
visitDetail(id: string) {
|
|
230
|
+
cy.visit(`/dashboard/${this.slug}/${id}`)
|
|
231
|
+
return this
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// ============================================
|
|
235
|
+
// API-AWARE NAVIGATION
|
|
236
|
+
// ============================================
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Navigate to list and wait for API response
|
|
240
|
+
*/
|
|
241
|
+
visitListWithApiWait() {
|
|
242
|
+
this.setupApiIntercepts()
|
|
243
|
+
this.visitList()
|
|
244
|
+
this.api.waitForList()
|
|
245
|
+
return this
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Navigate to edit page and wait for form to be visible
|
|
250
|
+
*/
|
|
251
|
+
visitEditWithApiWait(id: string) {
|
|
252
|
+
this.setupApiIntercepts()
|
|
253
|
+
this.visitEdit(id)
|
|
254
|
+
this.waitForForm()
|
|
255
|
+
return this
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Navigate to detail page and wait for content
|
|
260
|
+
*/
|
|
261
|
+
visitDetailWithApiWait(id: string) {
|
|
262
|
+
this.setupApiIntercepts()
|
|
263
|
+
this.visitDetail(id)
|
|
264
|
+
this.waitForDetail()
|
|
265
|
+
return this
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// ============================================
|
|
269
|
+
// WAITS
|
|
270
|
+
// ============================================
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Wait for list page to be fully loaded
|
|
274
|
+
*/
|
|
275
|
+
waitForList() {
|
|
276
|
+
cy.url().should('include', `/dashboard/${this.slug}`)
|
|
277
|
+
cy.get(this.selectors.tableContainer, { timeout: 15000 }).should('be.visible')
|
|
278
|
+
return this
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Wait for form to be visible
|
|
283
|
+
*/
|
|
284
|
+
waitForForm() {
|
|
285
|
+
cy.get(this.selectors.form, { timeout: 15000 }).should('be.visible')
|
|
286
|
+
return this
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Wait for detail page to be loaded
|
|
291
|
+
*/
|
|
292
|
+
waitForDetail() {
|
|
293
|
+
cy.url().should('match', new RegExp(`/dashboard/${this.slug}/[a-z0-9-]+$`))
|
|
294
|
+
cy.get(this.selectors.editButton, { timeout: 15000 }).should('be.visible')
|
|
295
|
+
return this
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// ============================================
|
|
299
|
+
// TABLE ACTIONS
|
|
300
|
+
// ============================================
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Click the Add/Create button
|
|
304
|
+
*/
|
|
305
|
+
clickAdd() {
|
|
306
|
+
cy.get(this.selectors.addButton).click()
|
|
307
|
+
return this
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Type in the search input
|
|
312
|
+
*/
|
|
313
|
+
search(term: string) {
|
|
314
|
+
cy.get(this.selectors.search).clear().type(term)
|
|
315
|
+
return this
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Clear the search input
|
|
320
|
+
*/
|
|
321
|
+
clearSearch() {
|
|
322
|
+
cy.get(this.selectors.searchClear).click()
|
|
323
|
+
return this
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Click a specific row by ID
|
|
328
|
+
*/
|
|
329
|
+
clickRow(id: string) {
|
|
330
|
+
cy.get(this.selectors.row(id)).click()
|
|
331
|
+
return this
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Find and click a row containing specific text
|
|
336
|
+
*/
|
|
337
|
+
clickRowByText(text: string) {
|
|
338
|
+
cy.contains(this.selectors.rowGeneric, text).click()
|
|
339
|
+
return this
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Select a row checkbox
|
|
344
|
+
*/
|
|
345
|
+
selectRow(id: string) {
|
|
346
|
+
cy.get(this.selectors.rowSelect(id)).click()
|
|
347
|
+
return this
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Open the row menu (three dots)
|
|
352
|
+
*/
|
|
353
|
+
openRowMenu(id: string) {
|
|
354
|
+
cy.get(this.selectors.rowMenu(id)).click()
|
|
355
|
+
return this
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Click an action in the row menu
|
|
360
|
+
*/
|
|
361
|
+
clickRowAction(action: string, id: string) {
|
|
362
|
+
cy.get(this.selectors.rowAction(action, id)).click()
|
|
363
|
+
return this
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// ============================================
|
|
367
|
+
// FILTERS
|
|
368
|
+
// ============================================
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Open a filter dropdown
|
|
372
|
+
*/
|
|
373
|
+
openFilter(field: string) {
|
|
374
|
+
cy.get(this.selectors.filterTrigger(field)).click()
|
|
375
|
+
return this
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Select a filter option
|
|
380
|
+
*/
|
|
381
|
+
selectFilterOption(field: string, value: string) {
|
|
382
|
+
cy.get(this.selectors.filterOption(field, value)).click()
|
|
383
|
+
return this
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Open filter and select option (convenience method)
|
|
388
|
+
*/
|
|
389
|
+
selectFilter(field: string, value: string) {
|
|
390
|
+
this.openFilter(field)
|
|
391
|
+
this.selectFilterOption(field, value)
|
|
392
|
+
return this
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Remove a filter badge
|
|
397
|
+
*/
|
|
398
|
+
removeFilterBadge(field: string, value: string) {
|
|
399
|
+
cy.get(this.selectors.filterRemoveBadge(field, value)).click()
|
|
400
|
+
return this
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Clear all values for a filter
|
|
405
|
+
*/
|
|
406
|
+
clearFilter(field: string) {
|
|
407
|
+
cy.get(this.selectors.filterClearAll(field)).click()
|
|
408
|
+
return this
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// ============================================
|
|
412
|
+
// PAGINATION
|
|
413
|
+
// ============================================
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Go to next page
|
|
417
|
+
*/
|
|
418
|
+
nextPage() {
|
|
419
|
+
cy.get(this.selectors.pageNext).click()
|
|
420
|
+
return this
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Go to previous page
|
|
425
|
+
*/
|
|
426
|
+
prevPage() {
|
|
427
|
+
cy.get(this.selectors.pagePrev).click()
|
|
428
|
+
return this
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Go to first page
|
|
433
|
+
*/
|
|
434
|
+
firstPage() {
|
|
435
|
+
cy.get(this.selectors.pageFirst).click()
|
|
436
|
+
return this
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Go to last page
|
|
441
|
+
*/
|
|
442
|
+
lastPage() {
|
|
443
|
+
cy.get(this.selectors.pageLast).click()
|
|
444
|
+
return this
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Change page size
|
|
449
|
+
*/
|
|
450
|
+
setPageSize(size: string) {
|
|
451
|
+
cy.get(this.selectors.pageSize).click()
|
|
452
|
+
cy.get(this.selectors.pageSizeOption(size)).click()
|
|
453
|
+
return this
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// ============================================
|
|
457
|
+
// FORM ACTIONS
|
|
458
|
+
// ============================================
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Fill a text input field
|
|
462
|
+
*/
|
|
463
|
+
fillTextField(name: string, value: string) {
|
|
464
|
+
cy.get(this.selectors.field(name)).find('input').clear().type(value)
|
|
465
|
+
return this
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Fill a textarea field
|
|
470
|
+
*/
|
|
471
|
+
fillTextarea(name: string, value: string) {
|
|
472
|
+
cy.get(this.selectors.field(name)).find('textarea').clear().type(value)
|
|
473
|
+
return this
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Select an option in a combobox/select field
|
|
478
|
+
*/
|
|
479
|
+
selectOption(name: string, value: string) {
|
|
480
|
+
cy.get(this.selectors.field(name)).find('[role="combobox"]').click()
|
|
481
|
+
cy.get(`[data-cy="${this.slug}-field-${name}-option-${value}"]`).click()
|
|
482
|
+
return this
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Submit the form
|
|
487
|
+
*/
|
|
488
|
+
submitForm() {
|
|
489
|
+
cy.get(this.selectors.submitButton).click()
|
|
490
|
+
return this
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
// ============================================
|
|
495
|
+
// HEADER/DETAIL ACTIONS
|
|
496
|
+
// ============================================
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Click back button
|
|
500
|
+
*/
|
|
501
|
+
clickBack() {
|
|
502
|
+
cy.get(this.selectors.backButton).click()
|
|
503
|
+
return this
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Click edit button
|
|
508
|
+
*/
|
|
509
|
+
clickEdit() {
|
|
510
|
+
cy.get(this.selectors.editButton).click()
|
|
511
|
+
return this
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Click delete button
|
|
516
|
+
*/
|
|
517
|
+
clickDelete() {
|
|
518
|
+
cy.get(this.selectors.deleteButton).click()
|
|
519
|
+
return this
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Confirm delete in dialog
|
|
524
|
+
*/
|
|
525
|
+
confirmDelete() {
|
|
526
|
+
cy.get(this.selectors.deleteConfirm).click()
|
|
527
|
+
return this
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Cancel delete in dialog
|
|
532
|
+
*/
|
|
533
|
+
cancelDelete() {
|
|
534
|
+
cy.get(this.selectors.deleteCancel).click()
|
|
535
|
+
return this
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
// ============================================
|
|
539
|
+
// BULK ACTIONS
|
|
540
|
+
// ============================================
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Select all items using table header checkbox
|
|
544
|
+
*/
|
|
545
|
+
selectAll() {
|
|
546
|
+
cy.get(this.selectors.selectAll).click()
|
|
547
|
+
return this
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Click bulk delete button
|
|
552
|
+
*/
|
|
553
|
+
bulkDelete() {
|
|
554
|
+
cy.get(this.selectors.bulkDelete).click()
|
|
555
|
+
return this
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Confirm bulk delete
|
|
560
|
+
*/
|
|
561
|
+
confirmBulkDelete() {
|
|
562
|
+
cy.get(this.selectors.bulkDeleteConfirm).click()
|
|
563
|
+
return this
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Cancel bulk delete
|
|
568
|
+
*/
|
|
569
|
+
cancelBulkDelete() {
|
|
570
|
+
cy.get(this.selectors.bulkDeleteCancel).click()
|
|
571
|
+
return this
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Click bulk status button
|
|
576
|
+
*/
|
|
577
|
+
bulkChangeStatus() {
|
|
578
|
+
cy.get(this.selectors.bulkStatus).click()
|
|
579
|
+
return this
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Select status in bulk status dialog
|
|
584
|
+
*/
|
|
585
|
+
selectBulkStatus(value: string) {
|
|
586
|
+
cy.get(this.selectors.bulkStatusSelect).click()
|
|
587
|
+
cy.get(this.selectors.bulkStatusOption(value)).click()
|
|
588
|
+
return this
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Confirm bulk status change
|
|
593
|
+
*/
|
|
594
|
+
confirmBulkStatus() {
|
|
595
|
+
cy.get(this.selectors.bulkStatusConfirm).click()
|
|
596
|
+
return this
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Clear selection
|
|
601
|
+
*/
|
|
602
|
+
clearSelection() {
|
|
603
|
+
cy.get(this.selectors.bulkClear).click()
|
|
604
|
+
return this
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// ============================================
|
|
608
|
+
// ASSERTIONS
|
|
609
|
+
// ============================================
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Assert text is visible in the list
|
|
613
|
+
*/
|
|
614
|
+
assertInList(text: string) {
|
|
615
|
+
cy.contains(text).should('be.visible')
|
|
616
|
+
return this
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
/**
|
|
620
|
+
* Assert text is not in the list
|
|
621
|
+
*/
|
|
622
|
+
assertNotInList(text: string) {
|
|
623
|
+
cy.contains(text).should('not.exist')
|
|
624
|
+
return this
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Assert table is visible
|
|
629
|
+
*/
|
|
630
|
+
assertTableVisible() {
|
|
631
|
+
cy.get(this.selectors.table).should('be.visible')
|
|
632
|
+
return this
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Assert form is visible
|
|
637
|
+
*/
|
|
638
|
+
assertFormVisible() {
|
|
639
|
+
cy.get(this.selectors.form).should('be.visible')
|
|
640
|
+
return this
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Assert page title contains text
|
|
645
|
+
*/
|
|
646
|
+
assertPageTitle(expected: string) {
|
|
647
|
+
cy.get(this.selectors.title).should('contain.text', expected)
|
|
648
|
+
return this
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Assert row exists
|
|
653
|
+
*/
|
|
654
|
+
assertRowExists(id: string) {
|
|
655
|
+
cy.get(this.selectors.row(id)).should('exist')
|
|
656
|
+
return this
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* Assert row does not exist
|
|
661
|
+
*/
|
|
662
|
+
assertRowNotExists(id: string) {
|
|
663
|
+
cy.get(this.selectors.row(id)).should('not.exist')
|
|
664
|
+
return this
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Assert selection count
|
|
669
|
+
*/
|
|
670
|
+
assertSelectionCount(count: number) {
|
|
671
|
+
cy.get(this.selectors.selectionCount).should('contain.text', count.toString())
|
|
672
|
+
return this
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**
|
|
676
|
+
* Assert bulk bar is visible
|
|
677
|
+
*/
|
|
678
|
+
assertBulkBarVisible() {
|
|
679
|
+
cy.get(this.selectors.bulkBar).should('be.visible')
|
|
680
|
+
return this
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
/**
|
|
684
|
+
* Assert bulk bar is hidden
|
|
685
|
+
*/
|
|
686
|
+
assertBulkBarHidden() {
|
|
687
|
+
cy.get(this.selectors.bulkBar).should('not.be.visible')
|
|
688
|
+
return this
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
export default DashboardEntityPOM
|
|
@@ -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'
|