@nextsparkjs/testing 0.1.0-beta.39

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,817 @@
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
+ pageTitle: this.cySelector("entities.page.title", { slug }),
306
+ // Table
307
+ tableContainer: this.cySelector("entities.table.container", { slug }),
308
+ table: this.cySelector("entities.table.element", { slug }),
309
+ addButton: this.cySelector("entities.table.addButton", { slug }),
310
+ search: this.cySelector("entities.table.search", { slug }),
311
+ searchContainer: this.cySelector("entities.table.search", { slug }),
312
+ searchClear: this.cySelector("entities.search.clear", { slug }),
313
+ selectAll: this.cySelector("entities.table.selectAll", { slug }),
314
+ selectionCount: this.cySelector("entities.table.selectionCount", { slug }),
315
+ row: (id) => this.cySelector("entities.table.row", { slug, id }),
316
+ rowSelect: (id) => this.cySelector("entities.table.rowSelect", { slug, id }),
317
+ rowMenu: (id) => this.cySelector("entities.table.rowMenu", { slug, id }),
318
+ rowAction: (action, id) => this.cySelector("entities.table.rowAction", { slug, action, id }),
319
+ cell: (field, id) => this.cySelector("entities.table.cell", { slug, field, id }),
320
+ rowGeneric: `[data-cy^="${slug}-row-"]`,
321
+ // Pagination
322
+ pagination: this.cySelector("entities.pagination.container", { slug }),
323
+ pageSize: this.cySelector("entities.pagination.pageSize", { slug }),
324
+ pageSizeOption: (size) => this.cySelector("entities.pagination.pageSizeOption", { slug, size }),
325
+ pageInfo: this.cySelector("entities.pagination.pageInfo", { slug }),
326
+ pageFirst: this.cySelector("entities.pagination.first", { slug }),
327
+ pagePrev: this.cySelector("entities.pagination.prev", { slug }),
328
+ pageNext: this.cySelector("entities.pagination.next", { slug }),
329
+ pageLast: this.cySelector("entities.pagination.last", { slug }),
330
+ // Header (detail pages) - modes: view, edit, create
331
+ viewHeader: this.cySelector("entities.header.container", { slug, mode: "view" }),
332
+ editHeader: this.cySelector("entities.header.container", { slug, mode: "edit" }),
333
+ createHeader: this.cySelector("entities.header.container", { slug, mode: "create" }),
334
+ backButton: this.cySelector("entities.header.backButton", { slug }),
335
+ editButton: this.cySelector("entities.header.editButton", { slug }),
336
+ deleteButton: this.cySelector("entities.header.deleteButton", { slug }),
337
+ copyId: this.cySelector("entities.header.copyId", { slug }),
338
+ title: this.cySelector("entities.header.title", { slug }),
339
+ // Delete confirmation
340
+ deleteDialog: this.cySelector("entities.header.deleteDialog", { slug }),
341
+ deleteCancel: this.cySelector("entities.header.deleteCancel", { slug }),
342
+ deleteConfirm: this.cySelector("entities.header.deleteConfirm", { slug }),
343
+ // Form
344
+ form: this.cySelector("entities.form.container", { slug }),
345
+ field: (name) => this.cySelector("entities.form.field", { slug, name }),
346
+ submitButton: this.cySelector("entities.form.submitButton", { slug }),
347
+ // Filters
348
+ filter: (field) => this.cySelector("entities.filter.container", { slug, field }),
349
+ filterTrigger: (field) => this.cySelector("entities.filter.trigger", { slug, field }),
350
+ filterContent: (field) => this.cySelector("entities.filter.content", { slug, field }),
351
+ filterOption: (field, value) => this.cySelector("entities.filter.option", { slug, field, value }),
352
+ filterBadge: (field, value) => this.cySelector("entities.filter.badge", { slug, field, value }),
353
+ filterRemoveBadge: (field, value) => this.cySelector("entities.filter.removeBadge", { slug, field, value }),
354
+ filterClearAll: (field) => this.cySelector("entities.filter.clearAll", { slug, field }),
355
+ // Bulk actions
356
+ bulkBar: this.cySelector("entities.bulk.bar", { slug }),
357
+ bulkCount: this.cySelector("entities.bulk.count", { slug }),
358
+ bulkSelectAll: this.cySelector("entities.bulk.selectAll", { slug }),
359
+ bulkStatus: this.cySelector("entities.bulk.statusButton", { slug }),
360
+ bulkDelete: this.cySelector("entities.bulk.deleteButton", { slug }),
361
+ bulkClear: this.cySelector("entities.bulk.clearButton", { slug }),
362
+ // Bulk status dialog
363
+ bulkStatusDialog: this.cySelector("entities.bulk.statusDialog", { slug }),
364
+ bulkStatusSelect: this.cySelector("entities.bulk.statusSelect", { slug }),
365
+ bulkStatusOption: (value) => this.cySelector("entities.bulk.statusOption", { slug, value }),
366
+ bulkStatusCancel: this.cySelector("entities.bulk.statusCancel", { slug }),
367
+ bulkStatusConfirm: this.cySelector("entities.bulk.statusConfirm", { slug }),
368
+ // Bulk delete dialog
369
+ bulkDeleteDialog: this.cySelector("entities.bulk.deleteDialog", { slug }),
370
+ bulkDeleteCancel: this.cySelector("entities.bulk.deleteCancel", { slug }),
371
+ bulkDeleteConfirm: this.cySelector("entities.bulk.deleteConfirm", { slug }),
372
+ // Generic confirm dialog
373
+ confirmDialog: this.cySelector("entities.confirm.dialog", { slug }),
374
+ confirmCancel: this.cySelector("entities.confirm.cancel", { slug }),
375
+ confirmAction: this.cySelector("entities.confirm.action", { slug }),
376
+ // Parent delete confirmation (EntityDetailWrapper - generic, no slug)
377
+ parentDeleteConfirm: '[data-cy="confirm-delete"]',
378
+ parentDeleteCancel: '[data-cy="cancel-delete"]',
379
+ // Row action selectors (generic patterns for checking existence)
380
+ rowActionEditGeneric: `[data-cy^="${slug}-action-edit-"]`,
381
+ rowActionDeleteGeneric: `[data-cy^="${slug}-action-delete-"]`,
382
+ // Detail view
383
+ detail: this.cySelector("entities.detail.container", { slug })
384
+ };
385
+ }
386
+ // ============================================
387
+ // NAVIGATION
388
+ // ============================================
389
+ /**
390
+ * Navigate to entity list page
391
+ */
392
+ visitList() {
393
+ cy.visit(`/dashboard/${this.slug}`);
394
+ return this;
395
+ }
396
+ /**
397
+ * Navigate to create page
398
+ */
399
+ visitCreate() {
400
+ cy.visit(`/dashboard/${this.slug}/create`);
401
+ return this;
402
+ }
403
+ /**
404
+ * Navigate to edit page for specific entity
405
+ */
406
+ visitEdit(id) {
407
+ cy.visit(`/dashboard/${this.slug}/${id}/edit`);
408
+ return this;
409
+ }
410
+ /**
411
+ * Navigate to detail/view page for specific entity
412
+ */
413
+ visitDetail(id) {
414
+ cy.visit(`/dashboard/${this.slug}/${id}`);
415
+ return this;
416
+ }
417
+ // ============================================
418
+ // API-AWARE NAVIGATION
419
+ // ============================================
420
+ /**
421
+ * Navigate to list and wait for API response
422
+ */
423
+ visitListWithApiWait() {
424
+ this.setupApiIntercepts();
425
+ this.visitList();
426
+ this.api.waitForList();
427
+ return this;
428
+ }
429
+ /**
430
+ * Navigate to edit page and wait for form to be visible
431
+ */
432
+ visitEditWithApiWait(id) {
433
+ this.setupApiIntercepts();
434
+ this.visitEdit(id);
435
+ this.waitForForm();
436
+ return this;
437
+ }
438
+ /**
439
+ * Navigate to detail page and wait for content
440
+ */
441
+ visitDetailWithApiWait(id) {
442
+ this.setupApiIntercepts();
443
+ this.visitDetail(id);
444
+ this.waitForDetail();
445
+ return this;
446
+ }
447
+ // ============================================
448
+ // WAITS
449
+ // ============================================
450
+ /**
451
+ * Wait for list page to be fully loaded
452
+ */
453
+ waitForList() {
454
+ cy.url().should("include", `/dashboard/${this.slug}`);
455
+ cy.get(this.selectors.tableContainer, { timeout: 15e3 }).should("be.visible");
456
+ return this;
457
+ }
458
+ /**
459
+ * Wait for form to be visible
460
+ */
461
+ waitForForm() {
462
+ cy.get(this.selectors.form, { timeout: 15e3 }).should("be.visible");
463
+ return this;
464
+ }
465
+ /**
466
+ * Wait for detail page to be loaded
467
+ */
468
+ waitForDetail() {
469
+ cy.url().should("match", new RegExp(`/dashboard/${this.slug}/[a-z0-9-]+$`));
470
+ cy.get(this.selectors.editButton, { timeout: 15e3 }).should("be.visible");
471
+ return this;
472
+ }
473
+ // ============================================
474
+ // TABLE ACTIONS
475
+ // ============================================
476
+ /**
477
+ * Click the Add/Create button
478
+ */
479
+ clickAdd() {
480
+ cy.get(this.selectors.addButton).click();
481
+ return this;
482
+ }
483
+ /**
484
+ * Type in the search input
485
+ */
486
+ search(term) {
487
+ cy.get(this.selectors.search).clear().type(term);
488
+ return this;
489
+ }
490
+ /**
491
+ * Clear the search input
492
+ */
493
+ clearSearch() {
494
+ cy.get(this.selectors.searchClear).click();
495
+ return this;
496
+ }
497
+ /**
498
+ * Click a specific row by ID
499
+ */
500
+ clickRow(id) {
501
+ cy.get(this.selectors.row(id)).click();
502
+ return this;
503
+ }
504
+ /**
505
+ * Find and click a row containing specific text
506
+ */
507
+ clickRowByText(text) {
508
+ cy.contains(this.selectors.rowGeneric, text).click();
509
+ return this;
510
+ }
511
+ /**
512
+ * Select a row checkbox
513
+ */
514
+ selectRow(id) {
515
+ cy.get(this.selectors.rowSelect(id)).click();
516
+ return this;
517
+ }
518
+ /**
519
+ * Open the row menu (three dots)
520
+ */
521
+ openRowMenu(id) {
522
+ cy.get(this.selectors.rowMenu(id)).click();
523
+ return this;
524
+ }
525
+ /**
526
+ * Click an action in the row menu
527
+ */
528
+ clickRowAction(action, id) {
529
+ cy.get(this.selectors.rowAction(action, id)).click();
530
+ return this;
531
+ }
532
+ // ============================================
533
+ // FILTERS
534
+ // ============================================
535
+ /**
536
+ * Open a filter dropdown
537
+ */
538
+ openFilter(field) {
539
+ cy.get(this.selectors.filterTrigger(field)).click();
540
+ return this;
541
+ }
542
+ /**
543
+ * Select a filter option
544
+ */
545
+ selectFilterOption(field, value) {
546
+ cy.get(this.selectors.filterOption(field, value)).click();
547
+ return this;
548
+ }
549
+ /**
550
+ * Open filter and select option (convenience method)
551
+ */
552
+ selectFilter(field, value) {
553
+ this.openFilter(field);
554
+ this.selectFilterOption(field, value);
555
+ return this;
556
+ }
557
+ /**
558
+ * Remove a filter badge
559
+ */
560
+ removeFilterBadge(field, value) {
561
+ cy.get(this.selectors.filterRemoveBadge(field, value)).click();
562
+ return this;
563
+ }
564
+ /**
565
+ * Clear all values for a filter
566
+ */
567
+ clearFilter(field) {
568
+ cy.get(this.selectors.filterClearAll(field)).click();
569
+ return this;
570
+ }
571
+ // ============================================
572
+ // PAGINATION
573
+ // ============================================
574
+ /**
575
+ * Go to next page
576
+ */
577
+ nextPage() {
578
+ cy.get(this.selectors.pageNext).click();
579
+ return this;
580
+ }
581
+ /**
582
+ * Go to previous page
583
+ */
584
+ prevPage() {
585
+ cy.get(this.selectors.pagePrev).click();
586
+ return this;
587
+ }
588
+ /**
589
+ * Go to first page
590
+ */
591
+ firstPage() {
592
+ cy.get(this.selectors.pageFirst).click();
593
+ return this;
594
+ }
595
+ /**
596
+ * Go to last page
597
+ */
598
+ lastPage() {
599
+ cy.get(this.selectors.pageLast).click();
600
+ return this;
601
+ }
602
+ /**
603
+ * Change page size
604
+ */
605
+ setPageSize(size) {
606
+ cy.get(this.selectors.pageSize).click();
607
+ cy.get(this.selectors.pageSizeOption(size)).click();
608
+ return this;
609
+ }
610
+ // ============================================
611
+ // FORM ACTIONS
612
+ // ============================================
613
+ /**
614
+ * Fill a text input field
615
+ */
616
+ fillTextField(name, value) {
617
+ cy.get(this.selectors.field(name)).find("input").clear().type(value);
618
+ return this;
619
+ }
620
+ /**
621
+ * Fill a textarea field
622
+ */
623
+ fillTextarea(name, value) {
624
+ cy.get(this.selectors.field(name)).find("textarea").clear().type(value);
625
+ return this;
626
+ }
627
+ /**
628
+ * Select an option in a combobox/select field
629
+ */
630
+ selectOption(name, value) {
631
+ cy.get(this.selectors.field(name)).find('[role="combobox"]').click();
632
+ cy.get(`[data-cy="${this.slug}-field-${name}-option-${value}"]`).click();
633
+ return this;
634
+ }
635
+ /**
636
+ * Submit the form
637
+ */
638
+ submitForm() {
639
+ cy.get(this.selectors.submitButton).click();
640
+ return this;
641
+ }
642
+ // ============================================
643
+ // HEADER/DETAIL ACTIONS
644
+ // ============================================
645
+ /**
646
+ * Click back button
647
+ */
648
+ clickBack() {
649
+ cy.get(this.selectors.backButton).click();
650
+ return this;
651
+ }
652
+ /**
653
+ * Click edit button
654
+ */
655
+ clickEdit() {
656
+ cy.get(this.selectors.editButton).click();
657
+ return this;
658
+ }
659
+ /**
660
+ * Click delete button
661
+ */
662
+ clickDelete() {
663
+ cy.get(this.selectors.deleteButton).click();
664
+ return this;
665
+ }
666
+ /**
667
+ * Confirm delete in dialog
668
+ */
669
+ confirmDelete() {
670
+ cy.get(this.selectors.deleteConfirm).click();
671
+ return this;
672
+ }
673
+ /**
674
+ * Cancel delete in dialog
675
+ */
676
+ cancelDelete() {
677
+ cy.get(this.selectors.deleteCancel).click();
678
+ return this;
679
+ }
680
+ // ============================================
681
+ // BULK ACTIONS
682
+ // ============================================
683
+ /**
684
+ * Select all items using table header checkbox
685
+ */
686
+ selectAll() {
687
+ cy.get(this.selectors.selectAll).click();
688
+ return this;
689
+ }
690
+ /**
691
+ * Click bulk delete button
692
+ */
693
+ bulkDelete() {
694
+ cy.get(this.selectors.bulkDelete).click();
695
+ return this;
696
+ }
697
+ /**
698
+ * Confirm bulk delete
699
+ */
700
+ confirmBulkDelete() {
701
+ cy.get(this.selectors.bulkDeleteConfirm).click();
702
+ return this;
703
+ }
704
+ /**
705
+ * Cancel bulk delete
706
+ */
707
+ cancelBulkDelete() {
708
+ cy.get(this.selectors.bulkDeleteCancel).click();
709
+ return this;
710
+ }
711
+ /**
712
+ * Click bulk status button
713
+ */
714
+ bulkChangeStatus() {
715
+ cy.get(this.selectors.bulkStatus).click();
716
+ return this;
717
+ }
718
+ /**
719
+ * Select status in bulk status dialog
720
+ */
721
+ selectBulkStatus(value) {
722
+ cy.get(this.selectors.bulkStatusSelect).click();
723
+ cy.get(this.selectors.bulkStatusOption(value)).click();
724
+ return this;
725
+ }
726
+ /**
727
+ * Confirm bulk status change
728
+ */
729
+ confirmBulkStatus() {
730
+ cy.get(this.selectors.bulkStatusConfirm).click();
731
+ return this;
732
+ }
733
+ /**
734
+ * Clear selection
735
+ */
736
+ clearSelection() {
737
+ cy.get(this.selectors.bulkClear).click();
738
+ return this;
739
+ }
740
+ // ============================================
741
+ // ASSERTIONS
742
+ // ============================================
743
+ /**
744
+ * Assert text is visible in the list
745
+ */
746
+ assertInList(text) {
747
+ cy.contains(text).should("be.visible");
748
+ return this;
749
+ }
750
+ /**
751
+ * Assert text is not in the list
752
+ */
753
+ assertNotInList(text) {
754
+ cy.contains(text).should("not.exist");
755
+ return this;
756
+ }
757
+ /**
758
+ * Assert table is visible
759
+ */
760
+ assertTableVisible() {
761
+ cy.get(this.selectors.table).should("be.visible");
762
+ return this;
763
+ }
764
+ /**
765
+ * Assert form is visible
766
+ */
767
+ assertFormVisible() {
768
+ cy.get(this.selectors.form).should("be.visible");
769
+ return this;
770
+ }
771
+ /**
772
+ * Assert page title contains text
773
+ */
774
+ assertPageTitle(expected) {
775
+ cy.get(this.selectors.title).should("contain.text", expected);
776
+ return this;
777
+ }
778
+ /**
779
+ * Assert row exists
780
+ */
781
+ assertRowExists(id) {
782
+ cy.get(this.selectors.row(id)).should("exist");
783
+ return this;
784
+ }
785
+ /**
786
+ * Assert row does not exist
787
+ */
788
+ assertRowNotExists(id) {
789
+ cy.get(this.selectors.row(id)).should("not.exist");
790
+ return this;
791
+ }
792
+ /**
793
+ * Assert selection count
794
+ */
795
+ assertSelectionCount(count) {
796
+ cy.get(this.selectors.selectionCount).should("contain.text", count.toString());
797
+ return this;
798
+ }
799
+ /**
800
+ * Assert bulk bar is visible
801
+ */
802
+ assertBulkBarVisible() {
803
+ cy.get(this.selectors.bulkBar).should("be.visible");
804
+ return this;
805
+ }
806
+ /**
807
+ * Assert bulk bar is hidden
808
+ */
809
+ assertBulkBarHidden() {
810
+ cy.get(this.selectors.bulkBar).should("not.be.visible");
811
+ return this;
812
+ }
813
+ };
814
+
815
+ export { BasePOMCore, DashboardEntityPOMCore };
816
+ //# sourceMappingURL=index.js.map
817
+ //# sourceMappingURL=index.js.map