@nextsparkjs/testing 0.1.0-beta.100

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.
@@ -0,0 +1,810 @@
1
+ // src/pom/BasePOMCore.ts
2
+ var BasePOMCore = class {
3
+ /**
4
+ * Get a Cypress selector using the centralized selectors
5
+ * Wrapper for cySelector with a shorter name
6
+ *
7
+ * @example
8
+ * this.cy('auth.login.form')
9
+ * // Returns: '[data-cy="login-form"]'
10
+ *
11
+ * this.cy('entities.table.row', { slug: 'tasks', id: '123' })
12
+ * // Returns: '[data-cy="tasks-row-123"]'
13
+ */
14
+ cy(path, replacements) {
15
+ return this.cySelector(path, replacements);
16
+ }
17
+ /**
18
+ * Replaces placeholders in a selector pattern and wraps with data-cy attribute
19
+ *
20
+ * @param pattern - Selector pattern with {placeholder} syntax
21
+ * @param replacements - Object with placeholder values
22
+ * @returns Formatted data-cy selector string
23
+ *
24
+ * @example
25
+ * selector('{slug}-row-{id}', { slug: 'tasks', id: '123' })
26
+ * // Returns: '[data-cy="tasks-row-123"]'
27
+ */
28
+ selector(pattern, replacements = {}) {
29
+ let result = pattern;
30
+ for (const [key, value] of Object.entries(replacements)) {
31
+ result = result.replaceAll(`{${key}}`, String(value));
32
+ }
33
+ return `[data-cy="${result}"]`;
34
+ }
35
+ /**
36
+ * Wrapper for cy.get with selector pattern support
37
+ * @param pattern - Selector pattern or direct selector
38
+ * @param replacements - Optional placeholder replacements
39
+ */
40
+ get(pattern, replacements = {}) {
41
+ return cy.get(this.selector(pattern, replacements));
42
+ }
43
+ /**
44
+ * Generic wait with configurable timeout
45
+ * @param selector - CSS selector to wait for
46
+ * @param timeout - Max wait time in ms (default: 15000)
47
+ */
48
+ waitFor(selector, timeout = 15e3) {
49
+ cy.get(selector, { timeout }).should("be.visible");
50
+ return this;
51
+ }
52
+ /**
53
+ * Wait for URL to contain a specific path
54
+ * @param path - Path segment to check for
55
+ */
56
+ waitForUrl(path) {
57
+ cy.url().should("include", path);
58
+ return this;
59
+ }
60
+ /**
61
+ * Wait for URL to match a regex pattern
62
+ * @param pattern - RegExp to match against URL
63
+ */
64
+ waitForUrlMatch(pattern) {
65
+ cy.url().should("match", pattern);
66
+ return this;
67
+ }
68
+ /**
69
+ * Visit a URL and return self for chaining
70
+ * @param url - URL to visit
71
+ */
72
+ visit(url) {
73
+ cy.visit(url);
74
+ return this;
75
+ }
76
+ /**
77
+ * Wait for page to load (checks for body visible)
78
+ */
79
+ waitForPageLoad() {
80
+ cy.get("body").should("be.visible");
81
+ return this;
82
+ }
83
+ /**
84
+ * Get an element by selector
85
+ * @param selector - CSS selector
86
+ */
87
+ getElement(selector) {
88
+ return cy.get(selector);
89
+ }
90
+ /**
91
+ * Click on an element
92
+ * @param selector - CSS selector
93
+ */
94
+ click(selector) {
95
+ cy.get(selector).click();
96
+ return this;
97
+ }
98
+ /**
99
+ * Type text into an input
100
+ * @param selector - CSS selector
101
+ * @param text - Text to type
102
+ */
103
+ type(selector, text) {
104
+ cy.get(selector).clear().type(text);
105
+ return this;
106
+ }
107
+ /**
108
+ * Check if element exists
109
+ * @param selector - CSS selector
110
+ */
111
+ exists(selector) {
112
+ return cy.get(selector).should("exist");
113
+ }
114
+ /**
115
+ * Check if element is visible
116
+ * @param selector - CSS selector
117
+ */
118
+ isVisible(selector) {
119
+ return cy.get(selector).should("be.visible");
120
+ }
121
+ /**
122
+ * Check if element does not exist
123
+ * @param selector - CSS selector
124
+ */
125
+ notExists(selector) {
126
+ return cy.get(selector).should("not.exist");
127
+ }
128
+ };
129
+
130
+ // src/helpers/ApiInterceptor.ts
131
+ var ApiInterceptor = class {
132
+ constructor(slugOrConfig) {
133
+ if (typeof slugOrConfig === "string") {
134
+ this.slug = slugOrConfig;
135
+ this.endpoint = `/api/v1/${slugOrConfig}`;
136
+ } else {
137
+ this.slug = slugOrConfig.slug;
138
+ this.endpoint = slugOrConfig.customPath || `/api/v1/${slugOrConfig.slug}`;
139
+ }
140
+ }
141
+ // ============================================
142
+ // ACCESSORS
143
+ // ============================================
144
+ /** Get the API endpoint path */
145
+ get path() {
146
+ return this.endpoint;
147
+ }
148
+ /** Get the entity slug */
149
+ get entitySlug() {
150
+ return this.slug;
151
+ }
152
+ /** Get alias names for all operations */
153
+ get aliases() {
154
+ return {
155
+ list: `${this.slug}List`,
156
+ create: `${this.slug}Create`,
157
+ update: `${this.slug}Update`,
158
+ delete: `${this.slug}Delete`
159
+ };
160
+ }
161
+ // ============================================
162
+ // INTERCEPT SETUP
163
+ // ============================================
164
+ /**
165
+ * Setup intercepts for all CRUD operations
166
+ * Call this BEFORE navigation in beforeEach or at test start
167
+ *
168
+ * Note: We intercept both PUT and PATCH for updates since different
169
+ * APIs may use different HTTP methods for updates.
170
+ */
171
+ setupCrudIntercepts() {
172
+ cy.intercept("GET", `${this.endpoint}*`).as(this.aliases.list);
173
+ cy.intercept("POST", this.endpoint).as(this.aliases.create);
174
+ cy.intercept("PUT", `${this.endpoint}/*`).as(this.aliases.update);
175
+ cy.intercept("PATCH", `${this.endpoint}/*`).as(`${this.aliases.update}Patch`);
176
+ cy.intercept("DELETE", `${this.endpoint}/*`).as(this.aliases.delete);
177
+ return this;
178
+ }
179
+ /**
180
+ * Setup only list + create intercepts
181
+ * Useful for list pages with inline create
182
+ */
183
+ setupListIntercepts() {
184
+ cy.intercept("GET", `${this.endpoint}*`).as(this.aliases.list);
185
+ cy.intercept("POST", this.endpoint).as(this.aliases.create);
186
+ return this;
187
+ }
188
+ // ============================================
189
+ // WAIT METHODS
190
+ // ============================================
191
+ /**
192
+ * Wait for list response (GET)
193
+ * Use after navigation or after mutations to wait for refresh
194
+ */
195
+ waitForList(timeout = 1e4) {
196
+ return cy.wait(`@${this.aliases.list}`, { timeout });
197
+ }
198
+ /**
199
+ * Wait for create response (POST) and validate success status
200
+ */
201
+ waitForCreate(timeout = 1e4) {
202
+ return cy.wait(`@${this.aliases.create}`, { timeout }).its("response.statusCode").should("be.oneOf", [200, 201]);
203
+ }
204
+ /**
205
+ * Wait for update response (PATCH or PUT) and validate success status
206
+ * Waits for PATCH first (more common), falls back to PUT
207
+ */
208
+ waitForUpdate(timeout = 1e4) {
209
+ return cy.wait(`@${this.aliases.update}Patch`, { timeout }).its("response.statusCode").should("be.oneOf", [200, 201]);
210
+ }
211
+ /**
212
+ * Wait for delete response (DELETE) and validate success status
213
+ */
214
+ waitForDelete(timeout = 1e4) {
215
+ return cy.wait(`@${this.aliases.delete}`, { timeout }).its("response.statusCode").should("be.oneOf", [200, 204]);
216
+ }
217
+ // ============================================
218
+ // CONVENIENCE METHODS
219
+ // ============================================
220
+ /**
221
+ * Wait for list refresh (alias for waitForList)
222
+ * Semantic name for use after create/update/delete
223
+ */
224
+ waitForRefresh(timeout = 1e4) {
225
+ return this.waitForList(timeout);
226
+ }
227
+ /**
228
+ * Wait for create + list refresh
229
+ * Common pattern: create entity, wait for success, wait for list to refresh
230
+ */
231
+ waitForCreateAndRefresh(timeout = 1e4) {
232
+ this.waitForCreate(timeout);
233
+ return this.waitForList(timeout);
234
+ }
235
+ /**
236
+ * Wait for update + list refresh
237
+ * Common pattern: update entity, wait for success, wait for list to refresh
238
+ */
239
+ waitForUpdateAndRefresh(timeout = 1e4) {
240
+ this.waitForUpdate(timeout);
241
+ return this.waitForList(timeout);
242
+ }
243
+ /**
244
+ * Wait for delete + list refresh
245
+ * Common pattern: delete entity, wait for success, wait for list to refresh
246
+ */
247
+ waitForDeleteAndRefresh(timeout = 1e4) {
248
+ this.waitForDelete(timeout);
249
+ return this.waitForList(timeout);
250
+ }
251
+ };
252
+
253
+ // src/pom/DashboardEntityPOMCore.ts
254
+ var DashboardEntityPOMCore = class extends BasePOMCore {
255
+ constructor(entitySlugOrConfig) {
256
+ super();
257
+ this._api = null;
258
+ if (typeof entitySlugOrConfig === "string") {
259
+ this.slug = entitySlugOrConfig;
260
+ this.entityConfig = { slug: entitySlugOrConfig };
261
+ } else {
262
+ this.slug = entitySlugOrConfig.slug;
263
+ this.entityConfig = entitySlugOrConfig;
264
+ }
265
+ }
266
+ /**
267
+ * Get the entity slug (public accessor)
268
+ * Useful for building dynamic selectors and URLs in tests
269
+ */
270
+ get entitySlug() {
271
+ return this.slug;
272
+ }
273
+ // ============================================
274
+ // API INTERCEPTOR
275
+ // ============================================
276
+ /**
277
+ * Get or create ApiInterceptor instance for this entity
278
+ */
279
+ get api() {
280
+ if (!this._api) {
281
+ this._api = new ApiInterceptor(this.slug);
282
+ }
283
+ return this._api;
284
+ }
285
+ /**
286
+ * Setup API intercepts for all CRUD operations
287
+ * Call this BEFORE navigation
288
+ */
289
+ setupApiIntercepts() {
290
+ this.api.setupCrudIntercepts();
291
+ return this;
292
+ }
293
+ // ============================================
294
+ // SELECTORS (uses cySelector from theme)
295
+ // ============================================
296
+ /**
297
+ * Get all selectors for this entity, with placeholders replaced
298
+ * Uses the abstract cySelector method which themes implement
299
+ */
300
+ get selectors() {
301
+ const slug = this.slug;
302
+ return {
303
+ // Page
304
+ page: this.cySelector("entities.page.container", { slug }),
305
+ // List - Table
306
+ tableContainer: this.cySelector("entities.list.table.container", { slug }),
307
+ table: this.cySelector("entities.list.table.element", { slug }),
308
+ addButton: this.cySelector("entities.list.addButton", { slug }),
309
+ selectAll: this.cySelector("entities.list.table.selectAll", { slug }),
310
+ selectionCount: this.cySelector("entities.list.selectionCount", { slug }),
311
+ row: (id) => this.cySelector("entities.list.table.row.element", { slug, id }),
312
+ rowSelect: (id) => this.cySelector("entities.list.table.row.checkbox", { slug, id }),
313
+ rowMenu: (id) => this.cySelector("entities.list.table.row.menu", { slug, id }),
314
+ rowAction: (action, id) => this.cySelector("entities.list.table.row.action", { slug, action, id }),
315
+ cell: (name, id) => this.cySelector("entities.list.table.cell.element", { slug, name, id }),
316
+ rowGeneric: `[data-cy^="${slug}-row-"]`,
317
+ // List - Search
318
+ search: this.cySelector("entities.list.search.input", { slug }),
319
+ searchContainer: this.cySelector("entities.list.search.container", { slug }),
320
+ searchClear: this.cySelector("entities.list.search.clear", { slug }),
321
+ // List - Pagination
322
+ pagination: this.cySelector("entities.list.pagination.container", { slug }),
323
+ pageSize: this.cySelector("entities.list.pagination.pageSize", { slug }),
324
+ pageSizeOption: (size) => this.cySelector("entities.list.pagination.pageSizeOption", { slug, size }),
325
+ pageInfo: this.cySelector("entities.list.pagination.info", { slug }),
326
+ pageFirst: this.cySelector("entities.list.pagination.first", { slug }),
327
+ pagePrev: this.cySelector("entities.list.pagination.prev", { slug }),
328
+ pageNext: this.cySelector("entities.list.pagination.next", { slug }),
329
+ pageLast: this.cySelector("entities.list.pagination.last", { slug }),
330
+ // List - Filters
331
+ filter: (field) => this.cySelector("entities.list.filters.container", { slug, field }),
332
+ filterTrigger: (field) => this.cySelector("entities.list.filters.trigger", { slug, field }),
333
+ filterContent: (field) => this.cySelector("entities.list.filters.content", { slug, field }),
334
+ filterOption: (field, value) => this.cySelector("entities.list.filters.option", { slug, field, value }),
335
+ filterBadge: (field, value) => this.cySelector("entities.list.filters.badge", { slug, field, value }),
336
+ filterRemoveBadge: (field, value) => this.cySelector("entities.list.filters.removeBadge", { slug, field, value }),
337
+ filterClearAll: (field) => this.cySelector("entities.list.filters.clearAll", { slug, field }),
338
+ // List - Bulk actions
339
+ bulkBar: this.cySelector("entities.list.bulk.bar", { slug }),
340
+ bulkCount: this.cySelector("entities.list.bulk.count", { slug }),
341
+ bulkSelectAll: this.cySelector("entities.list.bulk.selectAll", { slug }),
342
+ bulkStatus: this.cySelector("entities.list.bulk.statusButton", { slug }),
343
+ bulkDelete: this.cySelector("entities.list.bulk.deleteButton", { slug }),
344
+ bulkClear: this.cySelector("entities.list.bulk.clearButton", { slug }),
345
+ // List - Bulk status dialog
346
+ bulkStatusDialog: this.cySelector("entities.list.bulk.statusDialog", { slug }),
347
+ bulkStatusSelect: this.cySelector("entities.list.bulk.statusSelect", { slug }),
348
+ bulkStatusOption: (value) => this.cySelector("entities.list.bulk.statusOption", { slug, value }),
349
+ bulkStatusCancel: this.cySelector("entities.list.bulk.statusCancel", { slug }),
350
+ bulkStatusConfirm: this.cySelector("entities.list.bulk.statusConfirm", { slug }),
351
+ // List - Bulk delete dialog
352
+ bulkDeleteDialog: this.cySelector("entities.list.bulk.deleteDialog", { slug }),
353
+ bulkDeleteCancel: this.cySelector("entities.list.bulk.deleteCancel", { slug }),
354
+ bulkDeleteConfirm: this.cySelector("entities.list.bulk.deleteConfirm", { slug }),
355
+ // List - Confirm dialogs (for row actions)
356
+ confirmDialog: this.cySelector("entities.list.confirm.dialog", { slug }),
357
+ confirmCancel: this.cySelector("entities.list.confirm.cancel", { slug }),
358
+ confirmAction: this.cySelector("entities.list.confirm.action", { slug }),
359
+ // Header (detail pages) - modes: view, edit, create
360
+ viewHeader: this.cySelector("entities.header.container", { slug, mode: "view" }),
361
+ editHeader: this.cySelector("entities.header.container", { slug, mode: "edit" }),
362
+ createHeader: this.cySelector("entities.header.container", { slug, mode: "create" }),
363
+ backButton: this.cySelector("entities.header.backButton", { slug }),
364
+ editButton: this.cySelector("entities.header.editButton", { slug }),
365
+ deleteButton: this.cySelector("entities.header.deleteButton", { slug }),
366
+ title: this.cySelector("entities.header.title", { slug }),
367
+ // Header - Delete confirmation
368
+ deleteDialog: this.cySelector("entities.header.deleteDialog", { slug }),
369
+ deleteCancel: this.cySelector("entities.header.deleteCancel", { slug }),
370
+ deleteConfirm: this.cySelector("entities.header.deleteConfirm", { slug }),
371
+ // Detail view
372
+ detail: this.cySelector("entities.detail.container", { slug }),
373
+ // Form
374
+ form: this.cySelector("entities.form.container", { slug }),
375
+ field: (name) => this.cySelector("entities.form.field", { slug, name }),
376
+ submitButton: this.cySelector("entities.form.submitButton", { slug }),
377
+ // Parent delete confirmation (EntityDetailWrapper - generic, no slug)
378
+ parentDeleteConfirm: '[data-cy="confirm-delete"]',
379
+ parentDeleteCancel: '[data-cy="cancel-delete"]',
380
+ // Row action selectors (generic patterns for checking existence)
381
+ rowActionEditGeneric: `[data-cy^="${slug}-action-edit-"]`,
382
+ rowActionDeleteGeneric: `[data-cy^="${slug}-action-delete-"]`
383
+ };
384
+ }
385
+ // ============================================
386
+ // NAVIGATION
387
+ // ============================================
388
+ /**
389
+ * Navigate to entity list page
390
+ */
391
+ visitList() {
392
+ cy.visit(`/dashboard/${this.slug}`);
393
+ return this;
394
+ }
395
+ /**
396
+ * Navigate to create page
397
+ */
398
+ visitCreate() {
399
+ cy.visit(`/dashboard/${this.slug}/create`);
400
+ return this;
401
+ }
402
+ /**
403
+ * Navigate to edit page for specific entity
404
+ */
405
+ visitEdit(id) {
406
+ cy.visit(`/dashboard/${this.slug}/${id}/edit`);
407
+ return this;
408
+ }
409
+ /**
410
+ * Navigate to detail/view page for specific entity
411
+ */
412
+ visitDetail(id) {
413
+ cy.visit(`/dashboard/${this.slug}/${id}`);
414
+ return this;
415
+ }
416
+ // ============================================
417
+ // API-AWARE NAVIGATION
418
+ // ============================================
419
+ /**
420
+ * Navigate to list and wait for API response
421
+ */
422
+ visitListWithApiWait() {
423
+ this.setupApiIntercepts();
424
+ this.visitList();
425
+ this.api.waitForList();
426
+ return this;
427
+ }
428
+ /**
429
+ * Navigate to edit page and wait for form to be visible
430
+ */
431
+ visitEditWithApiWait(id) {
432
+ this.setupApiIntercepts();
433
+ this.visitEdit(id);
434
+ this.waitForForm();
435
+ return this;
436
+ }
437
+ /**
438
+ * Navigate to detail page and wait for content
439
+ */
440
+ visitDetailWithApiWait(id) {
441
+ this.setupApiIntercepts();
442
+ this.visitDetail(id);
443
+ this.waitForDetail();
444
+ return this;
445
+ }
446
+ // ============================================
447
+ // WAITS
448
+ // ============================================
449
+ /**
450
+ * Wait for list page to be fully loaded
451
+ */
452
+ waitForList() {
453
+ cy.url().should("include", `/dashboard/${this.slug}`);
454
+ cy.get(this.selectors.tableContainer, { timeout: 15e3 }).should("be.visible");
455
+ return this;
456
+ }
457
+ /**
458
+ * Wait for form to be visible
459
+ */
460
+ waitForForm() {
461
+ cy.get(this.selectors.form, { timeout: 15e3 }).should("be.visible");
462
+ return this;
463
+ }
464
+ /**
465
+ * Wait for detail page to be loaded
466
+ */
467
+ waitForDetail() {
468
+ cy.url().should("match", new RegExp(`/dashboard/${this.slug}/[a-z0-9-]+$`));
469
+ cy.get(this.selectors.editButton, { timeout: 15e3 }).should("be.visible");
470
+ return this;
471
+ }
472
+ // ============================================
473
+ // TABLE ACTIONS
474
+ // ============================================
475
+ /**
476
+ * Click the Add/Create button
477
+ */
478
+ clickAdd() {
479
+ cy.get(this.selectors.addButton).click();
480
+ return this;
481
+ }
482
+ /**
483
+ * Type in the search input
484
+ */
485
+ search(term) {
486
+ cy.get(this.selectors.search).clear().type(term);
487
+ return this;
488
+ }
489
+ /**
490
+ * Clear the search input
491
+ */
492
+ clearSearch() {
493
+ cy.get(this.selectors.searchClear).click();
494
+ return this;
495
+ }
496
+ /**
497
+ * Click a specific row by ID
498
+ */
499
+ clickRow(id) {
500
+ cy.get(this.selectors.row(id)).click();
501
+ return this;
502
+ }
503
+ /**
504
+ * Find and click a row containing specific text
505
+ */
506
+ clickRowByText(text) {
507
+ cy.contains(this.selectors.rowGeneric, text).click();
508
+ return this;
509
+ }
510
+ /**
511
+ * Select a row checkbox
512
+ */
513
+ selectRow(id) {
514
+ cy.get(this.selectors.rowSelect(id)).click();
515
+ return this;
516
+ }
517
+ /**
518
+ * Open the row menu (three dots)
519
+ */
520
+ openRowMenu(id) {
521
+ cy.get(this.selectors.rowMenu(id)).click();
522
+ return this;
523
+ }
524
+ /**
525
+ * Click an action in the row menu
526
+ */
527
+ clickRowAction(action, id) {
528
+ cy.get(this.selectors.rowAction(action, id)).click();
529
+ return this;
530
+ }
531
+ // ============================================
532
+ // FILTERS
533
+ // ============================================
534
+ /**
535
+ * Open a filter dropdown
536
+ */
537
+ openFilter(field) {
538
+ cy.get(this.selectors.filterTrigger(field)).click();
539
+ return this;
540
+ }
541
+ /**
542
+ * Select a filter option
543
+ */
544
+ selectFilterOption(field, value) {
545
+ cy.get(this.selectors.filterOption(field, value)).click();
546
+ return this;
547
+ }
548
+ /**
549
+ * Open filter and select option (convenience method)
550
+ */
551
+ selectFilter(field, value) {
552
+ this.openFilter(field);
553
+ this.selectFilterOption(field, value);
554
+ return this;
555
+ }
556
+ /**
557
+ * Clear all selected options for a specific filter
558
+ * NOTE: Clear button only appears when >1 option is selected
559
+ */
560
+ clearFilter(field) {
561
+ cy.get(this.selectors.filterClearAll(field)).click();
562
+ return this;
563
+ }
564
+ // ============================================
565
+ // PAGINATION
566
+ // ============================================
567
+ /**
568
+ * Go to next page
569
+ */
570
+ nextPage() {
571
+ cy.get(this.selectors.pageNext).click();
572
+ return this;
573
+ }
574
+ /**
575
+ * Go to previous page
576
+ */
577
+ prevPage() {
578
+ cy.get(this.selectors.pagePrev).click();
579
+ return this;
580
+ }
581
+ /**
582
+ * Go to first page
583
+ */
584
+ firstPage() {
585
+ cy.get(this.selectors.pageFirst).click();
586
+ return this;
587
+ }
588
+ /**
589
+ * Go to last page
590
+ */
591
+ lastPage() {
592
+ cy.get(this.selectors.pageLast).click();
593
+ return this;
594
+ }
595
+ /**
596
+ * Change page size
597
+ */
598
+ setPageSize(size) {
599
+ cy.get(this.selectors.pageSize).click();
600
+ cy.get(this.selectors.pageSizeOption(size)).click();
601
+ return this;
602
+ }
603
+ // ============================================
604
+ // FORM ACTIONS
605
+ // ============================================
606
+ /**
607
+ * Fill a text input field
608
+ */
609
+ fillTextField(name, value) {
610
+ cy.get(this.selectors.field(name)).find("input").clear().type(value);
611
+ return this;
612
+ }
613
+ /**
614
+ * Fill a textarea field
615
+ */
616
+ fillTextarea(name, value) {
617
+ cy.get(this.selectors.field(name)).find("textarea").clear().type(value);
618
+ return this;
619
+ }
620
+ /**
621
+ * Select an option in a combobox/select field
622
+ */
623
+ selectOption(name, value) {
624
+ cy.get(this.selectors.field(name)).find('[role="combobox"]').click();
625
+ cy.get(`[data-cy="${this.slug}-field-${name}-option-${value}"]`).click();
626
+ return this;
627
+ }
628
+ /**
629
+ * Submit the form
630
+ */
631
+ submitForm() {
632
+ cy.get(this.selectors.submitButton).click();
633
+ return this;
634
+ }
635
+ // ============================================
636
+ // HEADER/DETAIL ACTIONS
637
+ // ============================================
638
+ /**
639
+ * Click back button
640
+ */
641
+ clickBack() {
642
+ cy.get(this.selectors.backButton).click();
643
+ return this;
644
+ }
645
+ /**
646
+ * Click edit button
647
+ */
648
+ clickEdit() {
649
+ cy.get(this.selectors.editButton).click();
650
+ return this;
651
+ }
652
+ /**
653
+ * Click delete button
654
+ */
655
+ clickDelete() {
656
+ cy.get(this.selectors.deleteButton).click();
657
+ return this;
658
+ }
659
+ /**
660
+ * Confirm delete in dialog
661
+ */
662
+ confirmDelete() {
663
+ cy.get(this.selectors.deleteConfirm).click();
664
+ return this;
665
+ }
666
+ /**
667
+ * Cancel delete in dialog
668
+ */
669
+ cancelDelete() {
670
+ cy.get(this.selectors.deleteCancel).click();
671
+ return this;
672
+ }
673
+ // ============================================
674
+ // BULK ACTIONS
675
+ // ============================================
676
+ /**
677
+ * Select all items using table header checkbox
678
+ */
679
+ selectAll() {
680
+ cy.get(this.selectors.selectAll).click();
681
+ return this;
682
+ }
683
+ /**
684
+ * Click bulk delete button
685
+ */
686
+ bulkDelete() {
687
+ cy.get(this.selectors.bulkDelete).click();
688
+ return this;
689
+ }
690
+ /**
691
+ * Confirm bulk delete
692
+ */
693
+ confirmBulkDelete() {
694
+ cy.get(this.selectors.bulkDeleteConfirm).click();
695
+ return this;
696
+ }
697
+ /**
698
+ * Cancel bulk delete
699
+ */
700
+ cancelBulkDelete() {
701
+ cy.get(this.selectors.bulkDeleteCancel).click();
702
+ return this;
703
+ }
704
+ /**
705
+ * Click bulk status button
706
+ */
707
+ bulkChangeStatus() {
708
+ cy.get(this.selectors.bulkStatus).click();
709
+ return this;
710
+ }
711
+ /**
712
+ * Select status in bulk status dialog
713
+ */
714
+ selectBulkStatus(value) {
715
+ cy.get(this.selectors.bulkStatusSelect).click();
716
+ cy.get(this.selectors.bulkStatusOption(value)).click();
717
+ return this;
718
+ }
719
+ /**
720
+ * Confirm bulk status change
721
+ */
722
+ confirmBulkStatus() {
723
+ cy.get(this.selectors.bulkStatusConfirm).click();
724
+ return this;
725
+ }
726
+ /**
727
+ * Clear selection
728
+ */
729
+ clearSelection() {
730
+ cy.get(this.selectors.bulkClear).click();
731
+ return this;
732
+ }
733
+ // ============================================
734
+ // ASSERTIONS
735
+ // ============================================
736
+ /**
737
+ * Assert text is visible in the list
738
+ */
739
+ assertInList(text) {
740
+ cy.contains(text).should("be.visible");
741
+ return this;
742
+ }
743
+ /**
744
+ * Assert text is not in the list
745
+ */
746
+ assertNotInList(text) {
747
+ cy.contains(text).should("not.exist");
748
+ return this;
749
+ }
750
+ /**
751
+ * Assert table is visible
752
+ */
753
+ assertTableVisible() {
754
+ cy.get(this.selectors.table).should("be.visible");
755
+ return this;
756
+ }
757
+ /**
758
+ * Assert form is visible
759
+ */
760
+ assertFormVisible() {
761
+ cy.get(this.selectors.form).should("be.visible");
762
+ return this;
763
+ }
764
+ /**
765
+ * Assert page title contains text
766
+ */
767
+ assertPageTitle(expected) {
768
+ cy.get(this.selectors.title).should("contain.text", expected);
769
+ return this;
770
+ }
771
+ /**
772
+ * Assert row exists
773
+ */
774
+ assertRowExists(id) {
775
+ cy.get(this.selectors.row(id)).should("exist");
776
+ return this;
777
+ }
778
+ /**
779
+ * Assert row does not exist
780
+ */
781
+ assertRowNotExists(id) {
782
+ cy.get(this.selectors.row(id)).should("not.exist");
783
+ return this;
784
+ }
785
+ /**
786
+ * Assert selection count
787
+ */
788
+ assertSelectionCount(count) {
789
+ cy.get(this.selectors.selectionCount).should("contain.text", count.toString());
790
+ return this;
791
+ }
792
+ /**
793
+ * Assert bulk bar is visible
794
+ */
795
+ assertBulkBarVisible() {
796
+ cy.get(this.selectors.bulkBar).should("be.visible");
797
+ return this;
798
+ }
799
+ /**
800
+ * Assert bulk bar is hidden
801
+ */
802
+ assertBulkBarHidden() {
803
+ cy.get(this.selectors.bulkBar).should("not.be.visible");
804
+ return this;
805
+ }
806
+ };
807
+
808
+ export { BasePOMCore, DashboardEntityPOMCore };
809
+ //# sourceMappingURL=index.js.map
810
+ //# sourceMappingURL=index.js.map