|
| 1 | +import {type BOQuickAccessInterface} from '@interfaces/BO/quickAccess'; |
| 2 | +import BOBasePage from '@pages/BO/BOBasePage'; |
| 3 | +import {type Page} from '@playwright/test'; |
| 4 | + |
| 5 | +/** |
| 6 | + * Quick access page, contains functions that can be used on the page |
| 7 | + * @class |
| 8 | + * @extends BOBasePage |
| 9 | + */ |
| 10 | +class BOQuickAccess extends BOBasePage implements BOQuickAccessInterface { |
| 11 | + public readonly pageTitle: string; |
| 12 | + |
| 13 | + private readonly addNewQuickAccessButton: string; |
| 14 | + |
| 15 | + private readonly gridPanel: string; |
| 16 | + |
| 17 | + private readonly gridTitle: string; |
| 18 | + |
| 19 | + private readonly gridTable: string; |
| 20 | + |
| 21 | + private readonly filterRow: string; |
| 22 | + |
| 23 | + private readonly filterColumn: (filterBy: string) => string; |
| 24 | + |
| 25 | + private readonly filterSearchButton: string; |
| 26 | + |
| 27 | + private readonly filterResetButton: string; |
| 28 | + |
| 29 | + private readonly tableBody: string; |
| 30 | + |
| 31 | + private readonly tableBodyRows: string; |
| 32 | + |
| 33 | + private readonly tableBodyRow: (row: number) => string; |
| 34 | + |
| 35 | + private readonly tableBodyColumn: (row: number) => string; |
| 36 | + |
| 37 | + private readonly tableColumnId: (row: number) => string; |
| 38 | + |
| 39 | + private readonly tableColumnName: (row: number) => string; |
| 40 | + |
| 41 | + private readonly tableColumnLink: (row: number) => string; |
| 42 | + |
| 43 | + private readonly tableColumnIsNewWindow: (row: number) => string; |
| 44 | + |
| 45 | + private readonly bulkActionBlock: string; |
| 46 | + |
| 47 | + private readonly bulkActionMenuButton: string; |
| 48 | + |
| 49 | + private readonly bulkActionDropdownMenu: string; |
| 50 | + |
| 51 | + private readonly selectAllLink: string; |
| 52 | + |
| 53 | + private readonly bulkDeleteLink: string; |
| 54 | + |
| 55 | + /** |
| 56 | + * @constructs |
| 57 | + * Setting up texts and selectors to use on quick access page |
| 58 | + */ |
| 59 | + constructor() { |
| 60 | + super(); |
| 61 | + |
| 62 | + this.pageTitle = 'Quick Access •'; |
| 63 | + |
| 64 | + // Selectors |
| 65 | + // Header selectors |
| 66 | + this.addNewQuickAccessButton = 'a[data-role=page-header-desc-quick_access-link]'; |
| 67 | + |
| 68 | + // Panel |
| 69 | + this.gridPanel = '#form-quick_access .panel'; |
| 70 | + this.gridTitle = `${this.gridPanel} div.panel-heading span.badge`; |
| 71 | + |
| 72 | + // Table selectors |
| 73 | + this.gridTable = '#table-quick_access'; |
| 74 | + |
| 75 | + // Filter selectors |
| 76 | + this.filterRow = `${this.gridTable} tr.filter`; |
| 77 | + this.filterColumn = (filterBy: string) => `${this.filterRow} [name='quick_accessFilter_${filterBy}']`; |
| 78 | + this.filterSearchButton = '#submitFilterButtonquick_access'; |
| 79 | + this.filterResetButton = 'button[name=\'submitResetquick_access\']'; |
| 80 | + |
| 81 | + // Table body selectors |
| 82 | + this.tableBody = `${this.gridTable} tbody`; |
| 83 | + this.tableBodyRows = `${this.tableBody} tr`; |
| 84 | + this.tableBodyRow = (row: number) => `${this.tableBodyRows}:nth-child(${row})`; |
| 85 | + this.tableBodyColumn = (row: number) => `${this.tableBodyRow(row)} td`; |
| 86 | + |
| 87 | + // Columns selectors |
| 88 | + this.tableColumnId = (row: number) => `${this.tableBodyColumn(row)}:nth-child(2)`; |
| 89 | + this.tableColumnName = (row: number) => `${this.tableBodyColumn(row)}:nth-child(3)`; |
| 90 | + this.tableColumnLink = (row: number) => `${this.tableBodyColumn(row)}:nth-child(4)`; |
| 91 | + this.tableColumnIsNewWindow = (row: number) => `${this.tableBodyColumn(row)}:nth-child(5)`; |
| 92 | + |
| 93 | + // Bulk actions selectors |
| 94 | + this.bulkActionBlock = 'div.bulk-actions'; |
| 95 | + this.bulkActionMenuButton = '#bulk_action_menu_quick_access'; |
| 96 | + this.bulkActionDropdownMenu = `${this.bulkActionBlock} ul.dropdown-menu`; |
| 97 | + this.selectAllLink = `${this.bulkActionDropdownMenu} li:nth-child(1)`; |
| 98 | + this.bulkDeleteLink = `${this.bulkActionDropdownMenu} li:nth-child(4)`; |
| 99 | + } |
| 100 | + |
| 101 | + /* |
| 102 | + Methods |
| 103 | + */ |
| 104 | + |
| 105 | + /** |
| 106 | + * Go to add new quick access page |
| 107 | + * @param page {Page} Browser tab |
| 108 | + * @returns {Promise<void>} |
| 109 | + */ |
| 110 | + async goToAddNewQuickAccessPage(page: Page): Promise<void> { |
| 111 | + await this.clickAndWaitForURL(page, this.addNewQuickAccessButton); |
| 112 | + } |
| 113 | + |
| 114 | + /** |
| 115 | + * Get text from column in table |
| 116 | + * @param page {Page} Browser tab |
| 117 | + * @param row {number} Row index in the table |
| 118 | + * @param columnName {string} Column name in the table |
| 119 | + * @return {Promise<string>} |
| 120 | + */ |
| 121 | + async getTextColumn(page: Page, row: number, columnName: string): Promise<string> { |
| 122 | + let columnSelector: string; |
| 123 | + |
| 124 | + switch (columnName) { |
| 125 | + case 'id_quick_access': |
| 126 | + columnSelector = this.tableColumnId(row); |
| 127 | + break; |
| 128 | + |
| 129 | + case 'name': |
| 130 | + columnSelector = this.tableColumnName(row); |
| 131 | + break; |
| 132 | + |
| 133 | + case 'link': |
| 134 | + columnSelector = this.tableColumnLink(row); |
| 135 | + break; |
| 136 | + |
| 137 | + case 'new_window': |
| 138 | + columnSelector = this.tableColumnIsNewWindow(row); |
| 139 | + break; |
| 140 | + |
| 141 | + default: |
| 142 | + throw new Error(`Column ${columnName} was not found`); |
| 143 | + } |
| 144 | + |
| 145 | + return this.getTextContent(page, columnSelector); |
| 146 | + } |
| 147 | + |
| 148 | + /** |
| 149 | + * Filter quick access table |
| 150 | + * @param page {Page} Browser tab |
| 151 | + * @param filterType {string} Type of the filter (input or select) |
| 152 | + * @param filterBy {string} Value to use for the select type filter |
| 153 | + * @param value {string|number} Value for the select filter |
| 154 | + * @return {Promise<void>} |
| 155 | + */ |
| 156 | + async filterTable(page: Page, filterType: string, filterBy:string, value: string): Promise<void> { |
| 157 | + const currentUrl: string = page.url(); |
| 158 | + |
| 159 | + switch (filterType) { |
| 160 | + case 'input': |
| 161 | + await this.setValue(page, this.filterColumn(filterBy), value); |
| 162 | + await this.clickAndWaitForURL(page, this.filterSearchButton); |
| 163 | + break; |
| 164 | + |
| 165 | + case 'select': |
| 166 | + await Promise.all([ |
| 167 | + page.waitForURL((url: URL): boolean => url.toString() !== currentUrl, {waitUntil: 'networkidle'}), |
| 168 | + this.selectByVisibleText(page, this.filterColumn(filterBy), value ? 'Yes' : 'No'), |
| 169 | + ]); |
| 170 | + break; |
| 171 | + |
| 172 | + default: |
| 173 | + throw new Error(`Filter ${filterBy} was not found`); |
| 174 | + } |
| 175 | + } |
| 176 | + |
| 177 | + /** |
| 178 | + * Bulk delete link |
| 179 | + * @param page {Page} Browser tab |
| 180 | + * @return {Promise<string>} |
| 181 | + */ |
| 182 | + async bulkDeleteQuickAccessLink(page: Page): Promise<string> { |
| 183 | + // To confirm bulk delete action with dialog |
| 184 | + await this.dialogListener(page, true); |
| 185 | + |
| 186 | + // Select all rows |
| 187 | + await Promise.all([ |
| 188 | + page.locator(this.bulkActionMenuButton).click(), |
| 189 | + this.waitForVisibleSelector(page, this.selectAllLink), |
| 190 | + ]); |
| 191 | + |
| 192 | + await Promise.all([ |
| 193 | + page.locator(this.selectAllLink).click(), |
| 194 | + this.waitForHiddenSelector(page, this.selectAllLink), |
| 195 | + ]); |
| 196 | + |
| 197 | + // Perform delete |
| 198 | + await Promise.all([ |
| 199 | + page.locator(this.bulkActionMenuButton).click(), |
| 200 | + this.waitForVisibleSelector(page, this.bulkDeleteLink), |
| 201 | + ]); |
| 202 | + |
| 203 | + await this.clickAndWaitForURL(page, this.bulkDeleteLink); |
| 204 | + |
| 205 | + // Return successful message |
| 206 | + return this.getAlertSuccessBlockContent(page); |
| 207 | + } |
| 208 | + |
| 209 | + /** |
| 210 | + * Reset input filters |
| 211 | + * @param page {Page} Browser tab |
| 212 | + * @returns {Promise<void>} |
| 213 | + */ |
| 214 | + async resetFilter(page: Page): Promise<void> { |
| 215 | + if (!(await this.elementNotVisible(page, this.filterResetButton, 2000))) { |
| 216 | + await this.clickAndWaitForURL(page, this.filterResetButton); |
| 217 | + } |
| 218 | + } |
| 219 | + |
| 220 | + /** |
| 221 | + * Get number of elements in grid |
| 222 | + * @param page {Page} Browser tab |
| 223 | + * @returns {Promise<number>} |
| 224 | + */ |
| 225 | + async getNumberOfElementInGrid(page: Page): Promise<number> { |
| 226 | + return this.getNumberFromText(page, this.gridTitle); |
| 227 | + } |
| 228 | +} |
| 229 | + |
| 230 | +module.exports = new BOQuickAccess(); |
0 commit comments