@nextsparkjs/theme-default 0.1.0-beta.20 → 0.1.0-beta.22
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/support/e2e.ts +89 -0
- package/tests/cypress.config.ts +165 -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,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UAT Tests: DevTools API Tester
|
|
3
|
+
*
|
|
4
|
+
* This test suite validates the API Tester feature in DevTools.
|
|
5
|
+
* The API Tester allows developers to test API endpoints directly from the browser.
|
|
6
|
+
*
|
|
7
|
+
* Coverage:
|
|
8
|
+
* - Navigation to endpoint detail pages
|
|
9
|
+
* - HTTP method selection
|
|
10
|
+
* - Path parameter handling
|
|
11
|
+
* - Query parameter management
|
|
12
|
+
* - Request body (JSON payload) editing
|
|
13
|
+
* - Authentication modes (session/API key)
|
|
14
|
+
* - Request execution and cancellation
|
|
15
|
+
* - Response display (status, timing, body, headers)
|
|
16
|
+
*
|
|
17
|
+
* Session: 2025-12-30-devtools-api-mini-postman-v1
|
|
18
|
+
* Workflow Phase: 15 (qa-automation)
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { DevtoolsPOM } from '../../../src/features/DevtoolsPOM'
|
|
22
|
+
import { loginAsDefaultDeveloper } from '../../../src/session-helpers'
|
|
23
|
+
|
|
24
|
+
describe('DevTools API Tester UAT', () => {
|
|
25
|
+
const devtools = DevtoolsPOM.create()
|
|
26
|
+
|
|
27
|
+
beforeEach('Login as developer', () => {
|
|
28
|
+
// DevTools requires developer role
|
|
29
|
+
loginAsDefaultDeveloper()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
// ============================================
|
|
33
|
+
// UAT-001: Navigation to Endpoint Detail
|
|
34
|
+
// ACs: AC-NAV-01, AC-NAV-02
|
|
35
|
+
// ============================================
|
|
36
|
+
describe('UAT-001: Navigate to endpoint detail from list', () => {
|
|
37
|
+
it('should navigate to /devtools/api', () => {
|
|
38
|
+
devtools.visitApiList()
|
|
39
|
+
cy.url().should('include', '/devtools/api')
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('should click on an endpoint and navigate to detail page', () => {
|
|
43
|
+
devtools.visitApiList()
|
|
44
|
+
cy.wait(1000) // Wait for endpoints to load
|
|
45
|
+
|
|
46
|
+
// Click first endpoint
|
|
47
|
+
devtools.clickFirstEndpoint()
|
|
48
|
+
|
|
49
|
+
// Should navigate to detail page
|
|
50
|
+
cy.url().should('match', /\/devtools\/api\/v1\//)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('should show endpoint info and API tester on detail page', () => {
|
|
54
|
+
// Visit a known endpoint directly (e.g., /api/v1/profile)
|
|
55
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
56
|
+
|
|
57
|
+
devtools
|
|
58
|
+
.assertApiTesterVisible()
|
|
59
|
+
.assertEndpointInfoVisible()
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// ============================================
|
|
64
|
+
// UAT-002: Method Selector Shows Available Methods
|
|
65
|
+
// ACs: AC-MTH-01, AC-MTH-02
|
|
66
|
+
// ============================================
|
|
67
|
+
describe('UAT-002: Method selector shows available methods', () => {
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
// Visit endpoint with multiple methods (e.g., /api/v1/profile has GET, PATCH)
|
|
70
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('should show only available methods for the endpoint', () => {
|
|
74
|
+
// Profile endpoint should have GET and PATCH
|
|
75
|
+
devtools
|
|
76
|
+
.assertMethodExists('get')
|
|
77
|
+
.assertMethodExists('patch')
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('should have GET selected by default if available', () => {
|
|
81
|
+
cy.get('[data-cy="api-tester-method-get"]')
|
|
82
|
+
.should('have.class', 'ring-2') // Selected state has ring
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
// ============================================
|
|
87
|
+
// UAT-003: Method Selection Updates UI
|
|
88
|
+
// ACs: AC-MTH-03, AC-MTH-04
|
|
89
|
+
// ============================================
|
|
90
|
+
describe('UAT-003: Method selection updates UI (payload editor)', () => {
|
|
91
|
+
beforeEach(() => {
|
|
92
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('should NOT show payload editor for GET method', () => {
|
|
96
|
+
devtools.selectMethod('get')
|
|
97
|
+
devtools.assertPayloadEditorNotVisible()
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('should show payload editor when PATCH method is selected', () => {
|
|
101
|
+
devtools.selectMethod('patch')
|
|
102
|
+
devtools.assertPayloadEditorVisible()
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
// ============================================
|
|
107
|
+
// UAT-004: Path Parameters Detection and URL Preview
|
|
108
|
+
// ACs: AC-PATH-01, AC-PATH-02, AC-PATH-03
|
|
109
|
+
// ============================================
|
|
110
|
+
describe('UAT-004: Path parameters detected and URL preview updates', () => {
|
|
111
|
+
beforeEach(() => {
|
|
112
|
+
// Visit endpoint with path param (e.g., /api/v1/customers/[id])
|
|
113
|
+
devtools.visitApiEndpoint('/v1/customers/%5Bid%5D') // URL-encoded [id]
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it('should detect path parameters from endpoint pattern', () => {
|
|
117
|
+
cy.get('[data-cy="api-tester-path-params"]').should('exist')
|
|
118
|
+
cy.get('[data-cy="api-tester-path-param-id"]').should('exist')
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('should have labeled input field for path param', () => {
|
|
122
|
+
cy.get('[data-cy="api-tester-path-param-id-input"]').should('exist')
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('should update URL preview when path param value changes', () => {
|
|
126
|
+
// Initially URL preview should show [id] placeholder
|
|
127
|
+
devtools.assertUrlPreviewContains('/v1/customers/')
|
|
128
|
+
|
|
129
|
+
// Fill path param
|
|
130
|
+
devtools.fillPathParam('id', '12345')
|
|
131
|
+
|
|
132
|
+
// URL preview should now show the value
|
|
133
|
+
devtools.assertUrlPreviewContains('12345')
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
// ============================================
|
|
138
|
+
// UAT-005: Path Parameter Validation
|
|
139
|
+
// ACs: AC-PATH-04
|
|
140
|
+
// ============================================
|
|
141
|
+
describe('UAT-005: Path parameter validation (required params)', () => {
|
|
142
|
+
beforeEach(() => {
|
|
143
|
+
devtools.visitApiEndpoint('/v1/customers/%5Bid%5D')
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it('should show "required" badge on required path params', () => {
|
|
147
|
+
cy.get('[data-cy="api-tester-path-param-id"]')
|
|
148
|
+
.should('contain', 'required')
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
it('should disable Send button when required path param is empty', () => {
|
|
152
|
+
// Path param should be empty by default
|
|
153
|
+
cy.get('[data-cy="api-tester-send-btn"]').should('be.disabled')
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('should enable Send button when required path param is filled', () => {
|
|
157
|
+
devtools.fillPathParam('id', '12345')
|
|
158
|
+
cy.get('[data-cy="api-tester-send-btn"]').should('not.be.disabled')
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
// ============================================
|
|
163
|
+
// UAT-006: Query Parameters Add/Remove/Update URL
|
|
164
|
+
// ACs: AC-QRY-01, AC-QRY-02, AC-QRY-03, AC-QRY-04
|
|
165
|
+
// ============================================
|
|
166
|
+
describe('UAT-006: Query params add/remove and URL updates', () => {
|
|
167
|
+
beforeEach(() => {
|
|
168
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
it('should have key-value inputs for query params', () => {
|
|
172
|
+
cy.get('[data-cy="api-tester-query-editor"]').should('exist')
|
|
173
|
+
cy.get('[data-cy="api-tester-query-add-btn"]').should('exist')
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
it('should add query param row when Add button clicked', () => {
|
|
177
|
+
cy.get('[data-cy="api-tester-query-add-btn"]').click()
|
|
178
|
+
cy.get('[data-cy="api-tester-query-row-0"]').should('exist')
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
it('should update URL preview when query param is added', () => {
|
|
182
|
+
cy.get('[data-cy="api-tester-query-add-btn"]').click()
|
|
183
|
+
cy.get('[data-cy="api-tester-query-row-0-key"]').type('limit')
|
|
184
|
+
cy.get('[data-cy="api-tester-query-row-0-value"]').type('10')
|
|
185
|
+
|
|
186
|
+
devtools.assertUrlPreviewContains('limit=10')
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
it('should URL-encode query param values', () => {
|
|
190
|
+
cy.get('[data-cy="api-tester-query-add-btn"]').click()
|
|
191
|
+
cy.get('[data-cy="api-tester-query-row-0-key"]').type('filter')
|
|
192
|
+
cy.get('[data-cy="api-tester-query-row-0-value"]').type('status eq active')
|
|
193
|
+
|
|
194
|
+
// URLSearchParams should encode spaces as +
|
|
195
|
+
devtools.assertUrlPreviewContains('filter=status')
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
it('should remove query param row when delete button clicked', () => {
|
|
199
|
+
cy.get('[data-cy="api-tester-query-add-btn"]').click()
|
|
200
|
+
cy.get('[data-cy="api-tester-query-row-0"]').should('exist')
|
|
201
|
+
|
|
202
|
+
cy.get('[data-cy="api-tester-query-row-0-delete"]').click()
|
|
203
|
+
cy.get('[data-cy="api-tester-query-row-0"]').should('not.exist')
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
// ============================================
|
|
208
|
+
// UAT-007: JSON Payload Editor Validation
|
|
209
|
+
// ACs: AC-BODY-01, AC-BODY-02, AC-BODY-03
|
|
210
|
+
// ============================================
|
|
211
|
+
describe('UAT-007: JSON payload editor validation', () => {
|
|
212
|
+
beforeEach(() => {
|
|
213
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
214
|
+
devtools.selectMethod('patch')
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
it('should show JSON textarea for POST/PATCH/PUT methods', () => {
|
|
218
|
+
devtools.assertPayloadEditorVisible()
|
|
219
|
+
cy.get('[data-cy="api-tester-payload-textarea"]').should('exist')
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it('should show validation error for invalid JSON', () => {
|
|
223
|
+
devtools.fillPayload('{name: "test"}') // Invalid JSON (unquoted key)
|
|
224
|
+
|
|
225
|
+
devtools.assertPayloadErrorShown()
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
it('should NOT show error for valid JSON', () => {
|
|
229
|
+
devtools.fillPayload('{"name": "test"}')
|
|
230
|
+
|
|
231
|
+
cy.get('[data-cy="api-tester-payload-error"]').should('not.exist')
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
it('should disable Send button when JSON is invalid', () => {
|
|
235
|
+
devtools.fillPayload('{invalid}')
|
|
236
|
+
|
|
237
|
+
cy.get('[data-cy="api-tester-send-btn"]').should('be.disabled')
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
// ============================================
|
|
242
|
+
// UAT-008: Authentication Toggle Session/API Key
|
|
243
|
+
// ACs: AC-AUTH-01, AC-AUTH-04
|
|
244
|
+
// ============================================
|
|
245
|
+
describe('UAT-008: Authentication modes (session/API key)', () => {
|
|
246
|
+
beforeEach(() => {
|
|
247
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
it('should show authentication section', () => {
|
|
251
|
+
cy.get('[data-cy="api-tester-auth"]').should('exist')
|
|
252
|
+
cy.get('[data-cy="api-tester-auth-type"]').should('exist')
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('should have "Use current session" selected by default', () => {
|
|
256
|
+
cy.get('[data-cy="api-tester-auth-session"]')
|
|
257
|
+
.should('have.attr', 'data-state', 'checked')
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
it('should show API key input when "Use API key" is selected', () => {
|
|
261
|
+
// Initially API key input should not be visible
|
|
262
|
+
cy.get('[data-cy="api-tester-apikey-input"]').should('not.be.visible')
|
|
263
|
+
|
|
264
|
+
// Select API key option
|
|
265
|
+
devtools.selectAuthType('apiKey')
|
|
266
|
+
|
|
267
|
+
// API key input should now be visible
|
|
268
|
+
cy.get('[data-cy="api-tester-apikey-input"]').should('be.visible')
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
it('should hide API key input when switching back to session', () => {
|
|
272
|
+
devtools.selectAuthType('apiKey')
|
|
273
|
+
cy.get('[data-cy="api-tester-apikey-input"]').should('be.visible')
|
|
274
|
+
|
|
275
|
+
devtools.selectAuthType('session')
|
|
276
|
+
cy.get('[data-cy="api-tester-apikey-input"]').should('not.be.visible')
|
|
277
|
+
})
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
// ============================================
|
|
281
|
+
// UAT-009: Send Request and Display Response
|
|
282
|
+
// ACs: AC-EXEC-01, AC-EXEC-02, AC-RSP-01, AC-RSP-02, AC-RSP-04
|
|
283
|
+
// ============================================
|
|
284
|
+
describe('UAT-009: Send request and display response', () => {
|
|
285
|
+
beforeEach(() => {
|
|
286
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
it('should show idle state before sending request', () => {
|
|
290
|
+
cy.get('[data-cy="api-tester-response-idle"]').should('be.visible')
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
it('should execute request when Send button is clicked', () => {
|
|
294
|
+
devtools.clickSendRequest()
|
|
295
|
+
|
|
296
|
+
// Should show loading state
|
|
297
|
+
cy.get('[data-cy="api-tester-response-loading"]').should('be.visible')
|
|
298
|
+
|
|
299
|
+
// Wait for response
|
|
300
|
+
devtools.waitForResponse()
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
it('should display response status code with correct color', () => {
|
|
304
|
+
devtools.clickSendRequest()
|
|
305
|
+
devtools.waitForResponse()
|
|
306
|
+
|
|
307
|
+
// Status 200 should be visible
|
|
308
|
+
devtools.assertResponseStatus(200)
|
|
309
|
+
|
|
310
|
+
// Status badge should have green color (for 2xx)
|
|
311
|
+
cy.get('[data-cy="api-tester-response-status"]')
|
|
312
|
+
.should('have.class', 'bg-emerald-100')
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
it('should display response time in milliseconds', () => {
|
|
316
|
+
devtools.clickSendRequest()
|
|
317
|
+
devtools.waitForResponse()
|
|
318
|
+
|
|
319
|
+
devtools.assertResponseTimeVisible()
|
|
320
|
+
cy.get('[data-cy="api-tester-response-time"]')
|
|
321
|
+
.should('match', /\d+ms/)
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
it('should display formatted JSON body', () => {
|
|
325
|
+
devtools.clickSendRequest()
|
|
326
|
+
devtools.waitForResponse()
|
|
327
|
+
|
|
328
|
+
// Response body should be visible and formatted
|
|
329
|
+
cy.get('[data-cy="api-tester-response-body"]').should('be.visible')
|
|
330
|
+
cy.get('[data-cy="api-tester-response-body"]').should('contain', '{')
|
|
331
|
+
})
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
// ============================================
|
|
335
|
+
// UAT-010: Response Tabs (Body/Headers) and Status Colors
|
|
336
|
+
// ACs: AC-RSP-03, AC-RSP-06
|
|
337
|
+
// ============================================
|
|
338
|
+
describe('UAT-010: Response tabs and large response handling', () => {
|
|
339
|
+
beforeEach(() => {
|
|
340
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
341
|
+
devtools.clickSendRequest()
|
|
342
|
+
devtools.waitForResponse()
|
|
343
|
+
})
|
|
344
|
+
|
|
345
|
+
it('should have Body and Headers tabs', () => {
|
|
346
|
+
cy.get('[data-cy="api-tester-response-tab-body"]').should('exist')
|
|
347
|
+
cy.get('[data-cy="api-tester-response-tab-headers"]').should('exist')
|
|
348
|
+
})
|
|
349
|
+
|
|
350
|
+
it('should show body content by default', () => {
|
|
351
|
+
cy.get('[data-cy="api-tester-response-body"]').should('be.visible')
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
it('should switch to Headers tab when clicked', () => {
|
|
355
|
+
devtools.clickResponseHeadersTab()
|
|
356
|
+
|
|
357
|
+
cy.get('[data-cy="api-tester-response-headers"]').should('be.visible')
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
it('should display response headers as key-value pairs', () => {
|
|
361
|
+
devtools.clickResponseHeadersTab()
|
|
362
|
+
|
|
363
|
+
// Should show headers like "content-type: application/json"
|
|
364
|
+
cy.get('[data-cy="api-tester-response-headers"]').should('contain', ':')
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
it('should handle large responses with scrolling', () => {
|
|
368
|
+
// Response body should be in a ScrollArea
|
|
369
|
+
cy.get('[data-cy="api-tester-response-body"]')
|
|
370
|
+
.parent() // ScrollArea wrapper
|
|
371
|
+
.should('have.css', 'overflow', 'auto')
|
|
372
|
+
.or('have.css', 'overflow-y', 'auto')
|
|
373
|
+
})
|
|
374
|
+
})
|
|
375
|
+
|
|
376
|
+
// ============================================
|
|
377
|
+
// BONUS: Navigation Back to List
|
|
378
|
+
// AC: AC-NAV-03
|
|
379
|
+
// ============================================
|
|
380
|
+
describe('BONUS: Back navigation', () => {
|
|
381
|
+
it('should navigate back to list when back button is clicked', () => {
|
|
382
|
+
devtools.visitApiEndpoint('/v1/profile')
|
|
383
|
+
|
|
384
|
+
devtools.clickBackToList()
|
|
385
|
+
|
|
386
|
+
// Should be back at /devtools/api (no trailing path)
|
|
387
|
+
cy.url().should('eq', Cypress.config().baseUrl + '/devtools/api')
|
|
388
|
+
})
|
|
389
|
+
})
|
|
390
|
+
})
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
---
|
|
2
|
+
feature: Customers Management - Member Role
|
|
3
|
+
priority: high
|
|
4
|
+
tags: [customers, member, permissions, read-only, security]
|
|
5
|
+
grepTags: [uat, feat-customers, role-member, security]
|
|
6
|
+
coverage: 7
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Customers Management - Member Role (View Only - Restricted)
|
|
10
|
+
|
|
11
|
+
> Test suite for Member role customer permissions. Members can only READ customers - they CANNOT create, update, or delete. These tests verify proper UI restrictions for the Member role.
|
|
12
|
+
|
|
13
|
+
## Background
|
|
14
|
+
|
|
15
|
+
```gherkin:en
|
|
16
|
+
Given I am logged in as Member (member@nextspark.dev)
|
|
17
|
+
And I have navigated to the Customers dashboard
|
|
18
|
+
And the customers list has loaded successfully
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```gherkin:es
|
|
22
|
+
Given estoy logueado como Member (member@nextspark.dev)
|
|
23
|
+
And he navegado al dashboard de Clientes
|
|
24
|
+
And la lista de clientes ha cargado exitosamente
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## @test CUST-MEMBER-001: View customer list
|
|
30
|
+
|
|
31
|
+
### Metadata
|
|
32
|
+
- **Priority:** Critical
|
|
33
|
+
- **Type:** Smoke
|
|
34
|
+
- **Tags:** read, list, permissions
|
|
35
|
+
- **Grep:** `@smoke` `@critical`
|
|
36
|
+
|
|
37
|
+
```gherkin:en
|
|
38
|
+
Scenario: Member can view the customers table
|
|
39
|
+
|
|
40
|
+
Given I am logged in as a Member
|
|
41
|
+
When I navigate to the Customers dashboard
|
|
42
|
+
Then the customers page should be visible
|
|
43
|
+
And the customers table should be displayed
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
```gherkin:es
|
|
47
|
+
Scenario: Member puede ver la tabla de clientes
|
|
48
|
+
|
|
49
|
+
Given estoy logueado como Member
|
|
50
|
+
When navego al dashboard de Clientes
|
|
51
|
+
Then la pagina de clientes deberia estar visible
|
|
52
|
+
And la tabla de clientes deberia mostrarse
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Expected Results
|
|
56
|
+
- Customers dashboard is accessible to Member role
|
|
57
|
+
- Customers table displays with data
|
|
58
|
+
- Read access is properly granted
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## @test CUST-MEMBER-002: View customer details
|
|
63
|
+
|
|
64
|
+
### Metadata
|
|
65
|
+
- **Priority:** High
|
|
66
|
+
- **Type:** Regression
|
|
67
|
+
- **Tags:** read, details, navigation
|
|
68
|
+
|
|
69
|
+
```gherkin:en
|
|
70
|
+
Scenario: Member can view individual customer details
|
|
71
|
+
|
|
72
|
+
Given I am logged in as a Member
|
|
73
|
+
And there is at least one customer in the list
|
|
74
|
+
When I click on a customer row
|
|
75
|
+
Then I should be navigated to the customer detail page
|
|
76
|
+
And the URL should match /dashboard/customers/{id}
|
|
77
|
+
And the detail header should be visible
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```gherkin:es
|
|
81
|
+
Scenario: Member puede ver detalles de un cliente
|
|
82
|
+
|
|
83
|
+
Given estoy logueado como Member
|
|
84
|
+
And existe al menos un cliente en la lista
|
|
85
|
+
When hago clic en una fila de cliente
|
|
86
|
+
Then deberia ser navegado a la pagina de detalle
|
|
87
|
+
And la URL deberia coincidir con /dashboard/customers/{id}
|
|
88
|
+
And el encabezado de detalle deberia estar visible
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Expected Results
|
|
92
|
+
- Customer rows are clickable for Members
|
|
93
|
+
- Detail page navigation works
|
|
94
|
+
- Customer information is visible
|
|
95
|
+
- Detail header displays correctly
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## @test CUST-MEMBER-003: Edit button is hidden
|
|
100
|
+
|
|
101
|
+
### Metadata
|
|
102
|
+
- **Priority:** High
|
|
103
|
+
- **Type:** Regression
|
|
104
|
+
- **Tags:** update, security, hidden-button
|
|
105
|
+
- **Grep:** `@security`
|
|
106
|
+
|
|
107
|
+
```gherkin:en
|
|
108
|
+
Scenario: Edit button is hidden for Member role
|
|
109
|
+
|
|
110
|
+
Given I am logged in as a Member
|
|
111
|
+
And there is at least one customer in the list
|
|
112
|
+
When I click on a customer row to view details
|
|
113
|
+
Then I should see the customer information
|
|
114
|
+
But I should NOT see an "Edit" button
|
|
115
|
+
And the edit button should not exist in the DOM
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```gherkin:es
|
|
119
|
+
Scenario: Boton editar oculto para rol Member
|
|
120
|
+
|
|
121
|
+
Given estoy logueado como Member
|
|
122
|
+
And existe al menos un cliente en la lista
|
|
123
|
+
When hago clic en una fila para ver detalles
|
|
124
|
+
Then deberia ver la informacion del cliente
|
|
125
|
+
But NO deberia ver un boton "Editar"
|
|
126
|
+
And el boton editar no deberia existir en el DOM
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Expected Results
|
|
130
|
+
- Customer information is visible
|
|
131
|
+
- Edit button is completely hidden (not just disabled)
|
|
132
|
+
- Edit button does not exist in DOM
|
|
133
|
+
- Security: No way to access edit functionality
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## @test CUST-MEMBER-004: Create button is hidden
|
|
138
|
+
|
|
139
|
+
### Metadata
|
|
140
|
+
- **Priority:** Critical
|
|
141
|
+
- **Type:** Smoke
|
|
142
|
+
- **Tags:** create, security, hidden-button
|
|
143
|
+
- **Grep:** `@smoke` `@critical` `@security`
|
|
144
|
+
|
|
145
|
+
```gherkin:en
|
|
146
|
+
Scenario: Create button is hidden for Member role
|
|
147
|
+
|
|
148
|
+
Given I am logged in as a Member
|
|
149
|
+
When I navigate to the Customers list page
|
|
150
|
+
Then the customers page should be visible
|
|
151
|
+
But I should NOT see an "Add" button
|
|
152
|
+
And the create button should not exist in the DOM
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```gherkin:es
|
|
156
|
+
Scenario: Boton crear oculto para rol Member
|
|
157
|
+
|
|
158
|
+
Given estoy logueado como Member
|
|
159
|
+
When navego a la pagina de lista de Clientes
|
|
160
|
+
Then la pagina de clientes deberia estar visible
|
|
161
|
+
But NO deberia ver un boton "Agregar"
|
|
162
|
+
And el boton crear no deberia existir en el DOM
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Expected Results
|
|
166
|
+
- Customers list page loads correctly
|
|
167
|
+
- Add/Create button is completely hidden
|
|
168
|
+
- Create button does not exist in DOM
|
|
169
|
+
- Security: No way to access create functionality
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## @test CUST-MEMBER-005: No UI access to create form
|
|
174
|
+
|
|
175
|
+
### Metadata
|
|
176
|
+
- **Priority:** Medium
|
|
177
|
+
- **Type:** Regression
|
|
178
|
+
- **Tags:** create, security, form-access
|
|
179
|
+
|
|
180
|
+
```gherkin:en
|
|
181
|
+
Scenario: Member has no UI access to create form
|
|
182
|
+
|
|
183
|
+
Given I am logged in as a Member
|
|
184
|
+
When I am on the Customers list page
|
|
185
|
+
Then there should be no way to access the create form
|
|
186
|
+
And the "Add" button should not exist
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
```gherkin:es
|
|
190
|
+
Scenario: Member no tiene acceso UI al formulario de creacion
|
|
191
|
+
|
|
192
|
+
Given estoy logueado como Member
|
|
193
|
+
When estoy en la pagina de lista de Clientes
|
|
194
|
+
Then no deberia haber forma de acceder al formulario de creacion
|
|
195
|
+
And el boton "Agregar" no deberia existir
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Expected Results
|
|
199
|
+
- No UI element leads to create form
|
|
200
|
+
- Add button does not exist
|
|
201
|
+
- Create form is inaccessible through UI
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## @test CUST-MEMBER-006: Delete buttons are hidden
|
|
206
|
+
|
|
207
|
+
### Metadata
|
|
208
|
+
- **Priority:** Critical
|
|
209
|
+
- **Type:** Smoke
|
|
210
|
+
- **Tags:** delete, security, hidden-button
|
|
211
|
+
- **Grep:** `@smoke` `@critical` `@security`
|
|
212
|
+
|
|
213
|
+
```gherkin:en
|
|
214
|
+
Scenario: Delete buttons are hidden in list view
|
|
215
|
+
|
|
216
|
+
Given I am logged in as a Member
|
|
217
|
+
When I am on the Customers list page
|
|
218
|
+
Then I should NOT see any delete action buttons
|
|
219
|
+
And no delete buttons should exist in table rows
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
```gherkin:es
|
|
223
|
+
Scenario: Botones eliminar ocultos en vista de lista
|
|
224
|
+
|
|
225
|
+
Given estoy logueado como Member
|
|
226
|
+
When estoy en la pagina de lista de Clientes
|
|
227
|
+
Then NO deberia ver ningun boton de accion eliminar
|
|
228
|
+
And no deberian existir botones eliminar en las filas
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Expected Results
|
|
232
|
+
- No delete buttons visible in list view
|
|
233
|
+
- Delete actions do not exist in table rows
|
|
234
|
+
- Security: No way to trigger delete from list
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## @test CUST-MEMBER-007: No delete action in detail view
|
|
239
|
+
|
|
240
|
+
### Metadata
|
|
241
|
+
- **Priority:** High
|
|
242
|
+
- **Type:** Regression
|
|
243
|
+
- **Tags:** delete, security, detail-view
|
|
244
|
+
- **Grep:** `@security`
|
|
245
|
+
|
|
246
|
+
```gherkin:en
|
|
247
|
+
Scenario: Delete button is hidden in detail view
|
|
248
|
+
|
|
249
|
+
Given I am logged in as a Member
|
|
250
|
+
And there is at least one customer in the list
|
|
251
|
+
When I click on a customer row to view details
|
|
252
|
+
Then the detail page should load
|
|
253
|
+
And the detail header should be visible
|
|
254
|
+
But I should NOT see a "Delete" button
|
|
255
|
+
And the delete button should not exist in the DOM
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
```gherkin:es
|
|
259
|
+
Scenario: Boton eliminar oculto en vista de detalle
|
|
260
|
+
|
|
261
|
+
Given estoy logueado como Member
|
|
262
|
+
And existe al menos un cliente en la lista
|
|
263
|
+
When hago clic en una fila para ver detalles
|
|
264
|
+
Then la pagina de detalle deberia cargar
|
|
265
|
+
And el encabezado de detalle deberia estar visible
|
|
266
|
+
But NO deberia ver un boton "Eliminar"
|
|
267
|
+
And el boton eliminar no deberia existir en el DOM
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Expected Results
|
|
271
|
+
- Detail page loads correctly
|
|
272
|
+
- Detail header is visible
|
|
273
|
+
- Delete button is completely hidden
|
|
274
|
+
- Delete button does not exist in DOM
|
|
275
|
+
- Security: No way to trigger delete from detail view
|