diff --git a/.gitignore b/.gitignore index eafb7dbb..f3ddee4c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ node_modules/ test-results/ playwright-report/ .idea/ +.claude/ /tsconfig.tsbuildinfo /dist/ diff --git a/lib/helpers/BasePage.ts b/lib/helpers/BasePage.ts new file mode 100644 index 00000000..8858bcd6 --- /dev/null +++ b/lib/helpers/BasePage.ts @@ -0,0 +1,617 @@ +import {expect, Locator, Page} from "@playwright/test"; + +/** + * Base page class providing common UI interaction methods. + * All methods follow best practices for reliability: + * - click: Always checks element visibility before clicking + * - enterText: Always clears before filling text + * - select: Waits for element visibility before selecting + * + * @example + * ```typescript + * class MyPage extends BasePage { + * readonly submitBtn: Locator; + * + * constructor(page: Page) { + * super(page); + * this.submitBtn = page.getByRole('button', { name: 'Submit' }); + * } + * + * async submit() { + * await this.click(this.submitBtn); + * } + * } + * ``` + */ +export class BasePage { + readonly page: Page; + + constructor(page: Page) { + this.page = page; + } + + /** + * Clicks an element after verifying it is visible. + * @param locator - The element to click + * @param options - Optional click configuration + */ + async click(locator: Locator, options?: { force?: boolean; timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 7000 }); + await locator.click({ force: options?.force }); + } + + /** + * Double-clicks an element after verifying it is visible. + * @param locator - The element to double-click + * @param options - Optional configuration + */ + async doubleClick(locator: Locator, options?: { force?: boolean; timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.dblclick({ force: options?.force }); + } + + /** + * Right-clicks an element after verifying it is visible. + * @param locator - The element to right-click + * @param options - Optional configuration + */ + async rightClick(locator: Locator, options?: { force?: boolean; timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.click({ button: 'right', force: options?.force }); + } + + /** + * Clicks an element using JavaScript (bypasses actionability checks). + * Use when standard click doesn't work due to overlapping elements. + * @param locator - The element to click + */ + async forceClick(locator: Locator): Promise { + await locator.evaluate((el: HTMLElement) => el.click()); + } + + /** + * Enters text into an input field after clearing it. + * Verifies element visibility before interaction. + * @param locator - The input element + * @param text - The text to enter + * @param options - Optional configuration + */ + async enterText( + locator: Locator, + text: string, + options?: { clearFirst?: boolean; verify?: boolean; timeout?: number } + ): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + if (options?.clearFirst !== false) { + await locator.clear(); + } + await locator.fill(text); + if (options?.verify) { + await expect(locator).toHaveValue(text); + } + } + + /** + * Types text character by character (simulates real typing). + * Useful when fill() doesn't trigger necessary events. + * @param locator - The input element + * @param text - The text to type + * @param options - Optional configuration + */ + async typeText( + locator: Locator, + text: string, + options?: { clearFirst?: boolean; delay?: number; timeout?: number } + ): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + if (options?.clearFirst !== false) { + await locator.clear(); + } + await locator.pressSequentially(text, { delay: options?.delay ?? 50 }); + } + + /** + * Clears an input field. + * @param locator - The input element to clear + */ + async clearText(locator: Locator, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.clear(); + } + + /** + * Presses a keyboard key while focused on an element. + * @param locator - The element to focus + * @param key - The key to press (e.g., 'Enter', 'Tab', 'Escape') + */ + async pressKey(locator: Locator, key: string, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.press(key); + } + + /** + * Selects an option from a dropdown by value. + * @param locator - The select element + * @param value - The option value to select + */ + async selectByValue(locator: Locator, value: string, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.selectOption({ value }); + } + + /** + * Selects an option from a dropdown by visible text. + * @param locator - The select element + * @param text - The option text to select + */ + async selectByText(locator: Locator, text: string, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.selectOption({ label: text }); + } + + /** + * Selects an option from a dropdown by index. + * @param locator - The select element + * @param index - The option index to select (0-based) + */ + async selectByIndex(locator: Locator, index: number, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.selectOption({ index }); + } + + /** + * Selects multiple options from a multi-select dropdown. + * @param locator - The select element + * @param values - Array of option values to select + */ + async selectMultiple(locator: Locator, values: string[], options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.selectOption(values); + } + + /** + * Checks a checkbox if it's not already checked. + * @param locator - The checkbox element + */ + async check(locator: Locator, options?: { force?: boolean; timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.check({ force: options?.force }); + } + + /** + * Unchecks a checkbox if it's currently checked. + * @param locator - The checkbox element + */ + async uncheck(locator: Locator, options?: { force?: boolean; timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.uncheck({ force: options?.force }); + } + + /** + * Sets a checkbox to a specific state. + * @param locator - The checkbox element + * @param checked - Whether the checkbox should be checked + */ + async setChecked(locator: Locator, checked: boolean, options?: { force?: boolean; timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.setChecked(checked, { force: options?.force }); + } + + /** + * Hovers over an element. + * @param locator - The element to hover over + */ + async hover(locator: Locator, options?: { force?: boolean; timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.hover({ force: options?.force }); + } + + /** + * Focuses on an element. + * @param locator - The element to focus + */ + async focus(locator: Locator, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.focus(); + } + + /** + * Hovers over one element and clicks another (for menus that appear on hover). + * @param hoverLocator - The element to hover over + * @param clickLocator - The element to click after hover + */ + async hoverAndClick( + hoverLocator: Locator, + clickLocator: Locator, + options?: { force?: boolean; timeout?: number } + ): Promise { + await expect(hoverLocator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await hoverLocator.hover(); + await expect(clickLocator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await clickLocator.click({ force: options?.force }); + } + + /** + * Waits for an element to be visible. + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForVisible(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeVisible({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to be hidden. + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForHidden(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeHidden({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to be attached to the DOM. + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForAttached(locator: Locator, timeout?: number): Promise { + await locator.waitFor({ state: 'attached', timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to be detached from the DOM. + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForDetached(locator: Locator, timeout?: number): Promise { + await locator.waitFor({ state: 'detached', timeout: timeout ?? 5000 }); + } + + /** + * Waits for the page to finish loading (network idle). + */ + async waitForPageLoad(): Promise { + await this.page.waitForLoadState('networkidle'); + } + + /** + * Waits for the DOM to be fully loaded. + */ + async waitForDOMContentLoaded(): Promise { + await this.page.waitForLoadState('domcontentloaded'); + } + + /** + * Waits for all network requests to complete. + */ + async waitForLoadState(): Promise { + await this.page.waitForLoadState(); + } + + /** + * Waits for an element to be enabled. + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForEnabled(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeEnabled({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to be disabled. + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForDisabled(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeDisabled({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to contain specific text. + * @param locator - The element to wait for + * @param text - The text to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForText(locator: Locator, text: string, timeout?: number): Promise { + await expect(locator).toContainText(text, { timeout: timeout ?? 5000 }); + } + + /** + * Waits for an input to have a specific value. + * @param locator - The input element to wait for + * @param value - The value to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForValue(locator: Locator, value: string, timeout?: number): Promise { + await expect(locator).toHaveValue(value, { timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to have a specific attribute value. + * @param locator - The element to wait for + * @param name - The attribute name + * @param value - The expected attribute value + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForAttribute(locator: Locator, name: string, value: string | RegExp, timeout?: number): Promise { + await expect(locator).toHaveAttribute(name, value, { timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to have a specific CSS class. + * @param locator - The element to wait for + * @param className - The CSS class to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForClass(locator: Locator, className: string | RegExp, timeout?: number): Promise { + await expect(locator).toHaveClass(className, { timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to be editable. + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForEditable(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeEditable({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to be checked. + * @param locator - The checkbox/radio element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForChecked(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeChecked({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to be unchecked. + * @param locator - The checkbox/radio element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForUnchecked(locator: Locator, timeout?: number): Promise { + await expect(locator).not.toBeChecked({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for a specific URL or URL pattern. + * @param url - The URL string or regex pattern to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForURL(url: string | RegExp, timeout?: number): Promise { + await this.page.waitForURL(url, { timeout: timeout ?? 30000 }); + } + + /** + * Waits for a navigation to complete. + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForNavigation(timeout?: number): Promise { + await this.page.waitForLoadState('load', { timeout: timeout ?? 30000 }); + } + + /** + * Waits for a specific time (use sparingly, prefer explicit waits). + * @param milliseconds - Time to wait in milliseconds + */ + async waitForTimeout(milliseconds: number): Promise { + await this.page.waitForTimeout(milliseconds); + } + + /** + * Waits for a network request to a specific URL. + * @param urlOrPredicate - URL string, regex, or predicate function + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForRequest(urlOrPredicate: string | RegExp | ((request: any) => boolean), timeout?: number): Promise { + return await this.page.waitForRequest(urlOrPredicate, { timeout: timeout ?? 30000 }); + } + + /** + * Waits for a network response from a specific URL. + * @param urlOrPredicate - URL string, regex, or predicate function + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForResponse(urlOrPredicate: string | RegExp | ((response: any) => boolean), timeout?: number): Promise { + return await this.page.waitForResponse(urlOrPredicate, { timeout: timeout ?? 30000 }); + } + + /** + * Waits for an element to be focused. + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForFocused(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeFocused({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for an element to be empty (no text content). + * @param locator - The element to wait for + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForEmpty(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeEmpty({ timeout: timeout ?? 5000 }); + } + + /** + * Waits for a function to return true. + * @param predicate - Function that returns a boolean or Promise + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForFunction(predicate: () => boolean | Promise, timeout?: number): Promise { + await this.page.waitForFunction(predicate, { timeout: timeout ?? 30000 }); + } + + /** + * Waits for an element to have a specific CSS property value. + * @param locator - The element to wait for + * @param property - The CSS property name + * @param value - The expected CSS property value + * @param timeout - Maximum time to wait in milliseconds + */ + async waitForCSS(locator: Locator, property: string, value: string | RegExp, timeout?: number): Promise { + await expect(locator).toHaveCSS(property, value, { timeout: timeout ?? 5000 }); + } + + /** + * Asserts that an element is visible. + * @param locator - The element to check + * @param isVisible - Whether the element should be visible (default: true) + */ + async isVisible(locator: Locator, isVisible: boolean = true, timeout?: number): Promise { + await expect(locator).toBeVisible({ visible: isVisible, timeout: timeout ?? 5000 }); + } + + /** + * Asserts that an element is enabled. + * @param locator - The element to check + */ + async isEnabled(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeEnabled({ timeout: timeout ?? 5000 }); + } + + /** + * Asserts that an element is disabled. + * @param locator - The element to check + */ + async isDisabled(locator: Locator, timeout?: number): Promise { + await expect(locator).toBeDisabled({ timeout: timeout ?? 5000 }); + } + + /** + * Asserts that an element contains specific text. + * @param locator - The element to check + * @param text - The text to look for + */ + async containsText(locator: Locator, text: string, timeout?: number): Promise { + await expect(locator).toContainText(text, { timeout: timeout ?? 5000 }); + } + + /** + * Asserts that an element has specific text. + * @param locator - The element to check + * @param text - The exact text expected + */ + async hasText(locator: Locator, text: string, timeout?: number): Promise { + await expect(locator).toHaveText(text, { timeout: timeout ?? 5000 }); + } + + /** + * Asserts that an input has a specific value. + * @param locator - The input element to check + * @param value - The expected value + */ + async hasValue(locator: Locator, value: string, timeout?: number): Promise { + await expect(locator).toHaveValue(value, { timeout: timeout ?? 5000 }); + } + + /** + * Asserts that an element has a specific attribute value. + * @param locator - The element to check + * @param name - The attribute name + * @param value - The expected attribute value + */ + async hasAttribute(locator: Locator, name: string, value: string, timeout?: number): Promise { + await expect(locator).toHaveAttribute(name, value, { timeout: timeout ?? 5000 }); + } + + /** + * Asserts that a specific number of elements exist. + * @param locator - The locator to count + * @param count - The expected count + */ + async hasCount(locator: Locator, count: number, timeout?: number): Promise { + await expect(locator).toHaveCount(count, { timeout: timeout ?? 5000 }); + } + + /** + * Gets the text content of an element. + * @param locator - The element to get text from + * @returns The text content + */ + async getText(locator: Locator, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + return await locator.textContent() ?? ''; + } + + /** + * Gets the value of an input element. + * @param locator - The input element + * @returns The input value + */ + async getValue(locator: Locator, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + return await locator.inputValue(); + } + + /** + * Gets an attribute value from an element. + * @param locator - The element + * @param attributeName - The attribute name + * @returns The attribute value or null + */ + async getAttribute(locator: Locator, attributeName: string, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + return await locator.getAttribute(attributeName); + } + + /** + * Checks if an element is currently visible. + * @param locator - The element to check + * @returns True if visible, false otherwise + */ + async checkIsVisible(locator: Locator): Promise { + return await locator.isVisible(); + } + + /** + * Checks if a checkbox is checked. + * @param locator - The checkbox element + * @returns True if checked, false otherwise + */ + async isChecked(locator: Locator): Promise { + return await locator.isChecked(); + } + + /** + * Scrolls an element into view. + * @param locator - The element to scroll to + */ + async scrollIntoView(locator: Locator, options?: { timeout?: number }): Promise { + await expect(locator).toBeVisible({ timeout: options?.timeout ?? 5000 }); + await locator.scrollIntoViewIfNeeded(); + } + + /** + * Sets files on a file input element. + * @param locator - The file input element + * @param filePath - Path to the file(s) to set + */ + async setInputFiles(locator: Locator, filePath: string | string[]): Promise { + await locator.setInputFiles(filePath); + } + + /** + * Clears files from a file input. + * @param locator - The file input element + */ + async clearInputFiles(locator: Locator): Promise { + await locator.setInputFiles([]); + } + + /** + * Drags an element and drops it on another element. + * @param source - The element to drag + * @param target - The element to drop on + */ + async dragTo( + source: Locator, + target: Locator, + options?: { sourcePosition?: { x: number; y: number }; targetPosition?: { x: number; y: number } } + ): Promise { + await source.dragTo(target, options); + } + +} diff --git a/lib/helpers/ConstantHelper.ts b/lib/helpers/ConstantHelper.ts index db0c4234..259099b0 100644 --- a/lib/helpers/ConstantHelper.ts +++ b/lib/helpers/ConstantHelper.ts @@ -1,5 +1,24 @@ export class ConstantHelper { + public static readonly timeout = { + short: 1000, + medium: 5000, + long: 10000, + veryLong: 20000, + navigation: 30000, + pageLoad: 60000 + } + + public static readonly wait = { + minimal: 100, + short: 500, + medium: 1000, + long: 2000, + animation: 300, + debounce: 400, + networkIdle: 5000 + } + public static readonly sections = { content: "Content", media: "Media", diff --git a/lib/helpers/ContentRenderUiHelper.ts b/lib/helpers/ContentRenderUiHelper.ts index 3bcd97b1..5ecfd72f 100644 --- a/lib/helpers/ContentRenderUiHelper.ts +++ b/lib/helpers/ContentRenderUiHelper.ts @@ -18,9 +18,9 @@ export class ContentRenderUiHelper extends UiBaseLocators { async doesContentRenderValueContainText(text: string, isEqual: boolean = false) { if (isEqual) { - return await expect(this.contentRenderValue).toHaveText(text); + await this.hasText(this.contentRenderValue, text); } else { - return await expect(this.contentRenderValue).toContainText(text); + await this.containsText(this.contentRenderValue, text); } } @@ -34,6 +34,6 @@ export class ContentRenderUiHelper extends UiBaseLocators { } async doesDataSourceRenderValueHaveText(text: string) { - return await expect(this.dataSourceRenderValue).toHaveText(text); + await this.hasText(this.dataSourceRenderValue, text); } } \ No newline at end of file diff --git a/lib/helpers/ContentUiHelper.ts b/lib/helpers/ContentUiHelper.ts index 78717a72..19a26839 100644 --- a/lib/helpers/ContentUiHelper.ts +++ b/lib/helpers/ContentUiHelper.ts @@ -247,7 +247,7 @@ export class ContentUiHelper extends UiBaseLocators { this.hostnameComboBox = this.hostNameItem.locator('[label="Culture"]').locator('uui-combobox-list-option'); this.saveModalBtn = this.sidebarModal.getByLabel('Save', {exact: true}); this.resetFocalPointBtn = page.getByLabel('Reset focal point'); - this.addNewHostnameBtn = page.getByLabel('Add new hostname'); + this.addNewHostnameBtn = page.locator('umb-property-layout[label="Hostnames"]').locator('[label="Add new hostname"]'); // List View this.enterNameInContainerTxt = this.container.getByTestId('input:entity-name').locator('#input'); this.listView = page.locator('umb-document-table-collection-view'); @@ -370,44 +370,39 @@ export class ContentUiHelper extends UiBaseLocators { } async enterContentName(name: string) { - await expect(this.contentNameTxt).toBeVisible(); - await this.contentNameTxt.clear(); - await this.contentNameTxt.fill(name); - await expect(this.contentNameTxt).toHaveValue(name); + await this.enterText(this.contentNameTxt, name, {verify: true}); } async clickSaveAndPublishButton() { - await expect(this.saveAndPublishBtn).toBeVisible(); - await this.saveAndPublishBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.saveAndPublishBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async isSuccessStateVisibleForSaveAndPublishButton (isVisible: boolean = true){ const saveAndPublishBtn = this.workspaceAction.filter({has: this.saveAndPublishBtn}); - await expect(saveAndPublishBtn.locator(this.successState)).toBeVisible({visible: isVisible, timeout: 10000}); + await this.isVisible(saveAndPublishBtn.locator(this.successState), isVisible, ConstantHelper.timeout.long); } - + async clickPublishButton() { - await this.publishBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.publishBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickUnpublishButton() { - await this.unpublishBtn.click(); + await this.click(this.unpublishBtn); } async clickReloadChildrenThreeDotsButton() { - await this.reloadChildrenThreeDotsBtn.click(); + await this.click(this.reloadChildrenThreeDotsBtn); } async clickActionsMenuAtRoot() { - await this.actionMenuForContentBtn.click({force: true}); + await this.click(this.actionMenuForContentBtn, {force: true}); } async goToContentWithName(contentName: string) { const contentWithNameLocator = this.menuItemTree.getByText(contentName, {exact: true}); - await expect(contentWithNameLocator).toBeVisible(); - await contentWithNameLocator.click(); + await this.click(contentWithNameLocator, {timeout: ConstantHelper.timeout.long}); } async clickActionsMenuForContent(name: string) { @@ -424,8 +419,7 @@ export class ContentUiHelper extends UiBaseLocators { } async clickCaretButtonForContentName(name: string) { - await expect(this.menuItemTree.filter({hasText: name}).last().locator('#caret-button').last()).toBeVisible(); - await this.menuItemTree.filter({hasText: name}).last().locator('#caret-button').last().click(); + await this.click(this.menuItemTree.filter({hasText: name}).last().locator('#caret-button').last()); } async waitForModalVisible() { @@ -437,15 +431,12 @@ export class ContentUiHelper extends UiBaseLocators { } async clickSaveButtonForContent() { - await expect(this.saveContentBtn).toBeVisible(); - await this.saveContentBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.saveContentBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async enterTextstring(text: string) { - await expect(this.textstringTxt).toBeVisible(); - await this.textstringTxt.clear(); - await this.textstringTxt.fill(text); + await this.enterText(this.textstringTxt, text); } async isTextstringPropertyVisible(isVisible: boolean = true) { @@ -457,215 +448,207 @@ export class ContentUiHelper extends UiBaseLocators { } async doesContentTreeHaveName(contentName: string) { - await expect(this.contentTree).toContainText(contentName); + await this.containsText(this.contentTree, contentName); } async enterRichTextArea(value: string) { - await expect(this.richTextAreaTxt).toBeVisible(); + await this.waitForVisible(this.richTextAreaTxt); await this.richTextAreaTxt.fill(value); } async enterTextArea(value: string) { - await expect(this.textAreaTxt).toBeVisible(); - await this.page.waitForTimeout(200); - await this.textAreaTxt.clear(); - await this.textAreaTxt.fill(value); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); + await this.enterText(this.textAreaTxt, value); } async clickConfirmToUnpublishButton() { - await this.confirmToUnpublishBtn.click(); + await this.click(this.confirmToUnpublishBtn); } async clickCreateDocumentBlueprintButton() { - await this.createDocumentBlueprintBtn.click(); + await this.click(this.createDocumentBlueprintBtn); } // Info Tab async clickInfoTab() { - await expect(this.infoTab).toBeVisible(); - await this.infoTab.click(); + await this.click(this.infoTab); } async doesDocumentHaveLink(link: string) { - await expect(this.linkContent).toContainText(link); + await this.containsText(this.linkContent, link); } async doesHistoryHaveText(text: string) { - await expect(this.historyItems).toHaveText(text); + await this.hasText(this.historyItems, text); } async doesDocumentStateHaveText(text: string) { - await expect(this.documentState).toHaveText(text); + await this.hasText(this.documentState, text); } async doesCreatedDateHaveText(text: string) { - await expect(this.createdDate).toHaveText(text); + await this.hasText(this.createdDate, text); } async doesIdHaveText(text: string) { - await expect(this.id).toHaveText(text); + await this.hasText(this.id, text); } async clickEditDocumentTypeButton() { - await this.editDocumentTypeBtn.click(); + await this.click(this.editDocumentTypeBtn); } async clickAddTemplateButton() { - await this.addTemplateBtn.click(); + await this.click(this.addTemplateBtn); } async waitForContentToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); + // Extra wait as content creation seems to take a bit longer sometimes + await this.waitForTimeout(ConstantHelper.wait.short); } async waitForContentToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForContentToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForDomainToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForDomainToBeUpdated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForDomainToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForContentToBeTrashed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async clickDocumentTypeByName(documentTypeName: string) { - await this.page.locator('uui-ref-node-document-type[name="' + documentTypeName + '"]').click(); + await this.click(this.page.locator(`uui-ref-node-document-type[name="${documentTypeName}"]`)); } async clickTemplateByName(templateName: string) { - await this.page.locator('uui-ref-node[name="' + templateName + '"]').click(); + await this.click(this.page.locator(`uui-ref-node[name="${templateName}"]`)); } async isDocumentTypeModalVisible(documentTypeName: string) { - await expect(this.documentTypeWorkspace.filter({hasText: documentTypeName})).toBeVisible(); + await this.isVisible(this.documentTypeWorkspace.filter({hasText: documentTypeName})); } async isTemplateModalVisible(templateName: string) { - await expect(this.breadcrumbsTemplateModal.getByText(templateName)).toBeVisible(); + await this.isVisible(this.breadcrumbsTemplateModal.getByText(templateName)); } async clickEditTemplateByName(templateName: string) { - await this.page.locator('uui-ref-node[name="' + templateName + '"]').getByLabel('Choose').click(); + await this.click(this.page.locator(`uui-ref-node[name="${templateName}"]`).getByLabel('Choose')); } async changeTemplate(oldTemplate: string, newTemplate: string) { await this.clickEditTemplateByName(oldTemplate); - await this.sidebarModal.getByLabel(newTemplate).click(); + await this.click(this.sidebarModal.getByLabel(newTemplate)); await this.clickChooseModalButton(); } async isTemplateNameDisabled(templateName: string) { - await expect(this.sidebarModal.getByLabel(templateName)).toBeVisible(); - await expect(this.sidebarModal.getByLabel(templateName)).toBeDisabled(); + await this.isVisible(this.sidebarModal.getByLabel(templateName)); + await this.isDisabled(this.sidebarModal.getByLabel(templateName)); } // Culture and Hostnames async clickCultureAndHostnamesButton() { - await this.cultureAndHostnamesBtn.click(); + await this.click(this.cultureAndHostnamesBtn); } - + async clickAddNewHostnameButton(){ - await expect(this.addNewHostnameBtn).toBeVisible(); - await this.addNewHostnameBtn.click(); + await this.click(this.addNewHostnameBtn); } async selectCultureLanguageOption(option: string) { - await expect(this.cultureLanguageDropdownBox).toBeVisible(); - await this.cultureLanguageDropdownBox.click(); - await expect(this.page.getByText(option, {exact: true})).toBeVisible(); - await this.page.getByText(option, {exact: true}).click(); + await this.click(this.cultureLanguageDropdownBox); + await this.click(this.page.getByText(option, {exact: true})); } async selectHostnameLanguageOption(option: string, index: number = 0) { - await this.hostnameLanguageDropdownBox.nth(index).click(); - await this.hostnameComboBox.getByText(option).nth(index).click(); + await this.click(this.hostnameLanguageDropdownBox.nth(index)); + await this.click(this.hostnameComboBox.getByText(option).nth(index)); } async enterDomain(value: string, index: number = 0) { - await expect(this.hostnameTxt.nth(index)).toBeVisible(); - await this.hostnameTxt.nth(index).clear(); - await this.hostnameTxt.nth(index).fill(value); - await expect(this.hostnameTxt.nth(index)).toHaveValue(value); + await this.enterText(this.hostnameTxt.nth(index), value, {verify: true}); } async clickDeleteHostnameButton() { - await this.deleteHostnameBtn.first().click(); + await this.click(this.deleteHostnameBtn.first()); } async clickSaveModalButton() { - await this.saveModalBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.saveModalBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async chooseDocumentType(documentTypeName: string) { - await this.documentTypeNode.filter({hasText: documentTypeName}).click(); + await this.click(this.documentTypeNode.filter({hasText: documentTypeName})); } // Approved Color async clickApprovedColorByValue(value: string) { - await this.page.locator('uui-color-swatch[value="#' + value + '"] #swatch').click(); + await this.click(this.page.locator(`uui-color-swatch[value="#${value}"] #swatch`)); } // Checkbox list async chooseCheckboxListOption(optionValue: string) { - await this.page.locator('uui-checkbox[value="' + optionValue + '"] svg').click(); + await this.click(this.page.locator(`uui-checkbox[value="${optionValue}"] svg`)); } // Content Picker async addContentPicker(contentName: string) { await this.clickChooseButton(); - await this.sidebarModal.getByText(contentName).click(); - await this.chooseModalBtn.click(); + await this.click(this.sidebarModal.getByText(contentName)); + await this.click(this.chooseModalBtn); } async isOpenButtonVisibleInContentPicker(contentPickerName: string, isVisible: boolean = true) { - return expect(this.page.getByLabel('Open ' + contentPickerName)).toBeVisible({visible: isVisible}); + return await this.isVisible(this.page.getByLabel('Open ' + contentPickerName), isVisible); } async clickContentPickerOpenButton(contentPickerName: string) { - await this.page.getByLabel('Open ' + contentPickerName).click(); + await this.click(this.page.getByLabel('Open ' + contentPickerName)); } async isNodeOpenForContentPicker(contentPickerName: string) { - return expect(this.openedModal.getByText(contentPickerName)).toBeVisible(); + return await this.isVisible(this.openedModal.getByText(contentPickerName)); } async isContentNameVisible(contentName: string, isVisible: boolean = true) { - return expect(this.sidebarModal.getByText(contentName)).toBeVisible({visible: isVisible}); + return await this.isVisible(this.sidebarModal.getByText(contentName), isVisible); } async isContentInTreeVisible(name: string, isVisible: boolean = true) { - await expect(this.documentTreeItem.getByLabel(name, {exact: true}).first()).toBeVisible({visible: isVisible}); + await this.isVisible(this.documentTreeItem.getByLabel(name, {exact: true}).first(), isVisible); } async isChildContentInTreeVisible(parentName: string, childName: string, isVisible: boolean = true) { - await expect(this.documentTreeItem.locator('[label="' + parentName + '"]').getByLabel(childName)).toBeVisible({visible: isVisible}); + await this.isVisible(this.documentTreeItem.locator('[label="' + parentName + '"]').locator('uui-menu-item[label="' + childName + '"]'), isVisible); } async removeContentPicker(contentPickerName: string) { - const contentPickerLocator = this.entityItem.filter({has: this.page.locator('[name="' + contentPickerName + '"]')}); - await contentPickerLocator.hover(); - await contentPickerLocator.getByLabel('Remove').click(); + const contentPickerLocator = this.entityItem.filter({has: this.page.locator(`[name="${contentPickerName}"]`)}); + await this.hoverAndClick(contentPickerLocator, contentPickerLocator.getByLabel('Remove')); await this.clickConfirmRemoveButton(); } // Dropdown async chooseDropdownOption(optionValues: string[]) { - await this.dropdown.selectOption(optionValues); + await this.selectMultiple(this.dropdown, optionValues); } // Date Picker @@ -675,7 +658,7 @@ export class ContentUiHelper extends UiBaseLocators { // Media Picker async clickChooseMediaPickerButton() { - await this.chooseMediaPickerBtn.click(); + await this.click(this.chooseMediaPickerBtn); } async clickChooseButtonAndSelectMediaWithName(mediaName: string) { @@ -687,22 +670,22 @@ export class ContentUiHelper extends UiBaseLocators { await this.clickChooseMediaPickerButton(); await this.selectMediaWithTestId(mediaKey); } - + async removeMediaPickerByName(mediaPickerName: string) { - await this.page.locator('[name="' + mediaPickerName + '"] [label="Remove"] svg').click(); + await this.click(this.page.locator(`[name="${mediaPickerName}"] [label="Remove"] svg`)); await this.clickConfirmRemoveButton(); } async isMediaNameVisible(mediaName: string, isVisible: boolean = true) { - return expect(this.mediaCardItems.filter({hasText: mediaName})).toBeVisible({visible: isVisible}); + return await this.isVisible(this.mediaCardItems.filter({hasText: mediaName}), isVisible); } async clickResetFocalPointButton() { - await this.resetFocalPointBtn.click(); + await this.click(this.resetFocalPointBtn); } async setFocalPoint(widthPercentage: number = 50, heightPercentage: number = 50) { - await this.page.waitForTimeout(1000); + await this.page.waitForTimeout(ConstantHelper.wait.medium); const element = await this.page.locator('#image').boundingBox(); if (!element) { throw new Error('Element not found'); @@ -714,128 +697,121 @@ export class ContentUiHelper extends UiBaseLocators { const x = element.x + (element.width * widthPercentage) / 100; const y = element.y + (element.height * heightPercentage) / 100; - await this.page.waitForTimeout(200); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); await this.page.mouse.move(centerX, centerY, {steps: 5}); - await this.page.waitForTimeout(200); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); await this.page.mouse.down(); - await this.page.waitForTimeout(200); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); await this.page.mouse.move(x, y); - await this.page.waitForTimeout(200); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); await this.page.mouse.up(); } // Member Picker async clickChooseMemberPickerButton() { - await this.chooseMemberPickerBtn.click(); + await this.click(this.chooseMemberPickerBtn); } async selectMemberByName(memberName: string) { - await this.sidebarModal.getByText(memberName, {exact: true}).click(); + await this.click(this.sidebarModal.getByText(memberName, {exact: true})); } async removeMemberPickerByName(memberName: string) { - const mediaPickerLocator = this.entityItem.filter({has: this.page.locator('[name="' + memberName + '"]')}); - await mediaPickerLocator.hover(); - await mediaPickerLocator.getByLabel('Remove').click(); + const mediaPickerLocator = this.entityItem.filter({has: this.page.locator(`[name="${memberName}"]`)}); + await this.hoverAndClick(mediaPickerLocator, mediaPickerLocator.getByLabel('Remove')); await this.clickConfirmRemoveButton(); } // Numeric async enterNumeric(number: number) { - await this.numericTxt.clear(); - await this.numericTxt.fill(number.toString()); + await this.enterText(this.numericTxt, number.toString()); } // Radiobox async chooseRadioboxOption(optionValue: string) { - await this.page.locator('uui-radio[value="' + optionValue + '"] #button').click(); + await this.click(this.page.locator(`uui-radio[value="${optionValue}"] #button`)); } // Tags async clickPlusIconButton() { - await this.plusIconBtn.click(); + await this.click(this.plusIconBtn); } async enterTag(tagName: string) { - await this.enterTagTxt.fill(tagName); - await this.enterTagTxt.press('Enter'); + await this.enterText(this.enterTagTxt, tagName); + await this.pressKey(this.enterTagTxt, 'Enter'); } async removeTagByName(tagName: string) { - await expect(this.tagItems.filter({hasText: tagName}).locator('svg')).toBeVisible(); - await this.tagItems.filter({hasText: tagName}).locator('svg').click(); + await this.click(this.tagItems.filter({hasText: tagName}).locator('svg')); } // Multi URL Picker async clickAddMultiURLPickerButton() { - await this.addMultiURLPickerBtn.click(); + await this.click(this.addMultiURLPickerBtn); } async selectLinkByName(linkName: string) { - await expect(this.sidebarModal.getByText(linkName, {exact: true})).toBeVisible(); - await this.sidebarModal.getByText(linkName, {exact: true}).click(); + await this.click(this.sidebarModal.getByText(linkName, {exact: true})); } async enterLink(value: string, toPress: boolean = false) { - await this.linkTxt.clear(); if (toPress) { - await this.linkTxt.press(value); + await this.enterText(this.linkTxt, ''); + await this.pressKey(this.linkTxt, value); } else { - await this.linkTxt.fill(value); + await this.enterText(this.linkTxt, value); } } async enterAnchorOrQuerystring(value: string, toPress: boolean = false) { - await this.anchorQuerystringTxt.clear(); if (toPress) { - await this.anchorQuerystringTxt.press(value); + await this.enterText(this.anchorQuerystringTxt, ''); + await this.pressKey(this.anchorQuerystringTxt, value); } else { - await this.anchorQuerystringTxt.fill(value); + await this.enterText(this.anchorQuerystringTxt, value); } } async enterLinkTitle(value: string, toPress: boolean = false) { - await this.linkTitleTxt.clear(); if (toPress) { - await this.linkTitleTxt.press(value); + await this.enterText(this.linkTitleTxt, ''); + await this.pressKey(this.linkTitleTxt, value); } else { - await this.linkTitleTxt.fill(value); + await this.enterText(this.linkTitleTxt, value); } } async removeUrlPickerByName(linkName: string) { - await this.page.locator('[name="' + linkName + '"]').getByLabel('Remove').click(); + await this.click(this.page.locator(`[name="${linkName}"]`).getByLabel('Remove')); await this.clickConfirmRemoveButton(); } async clickEditUrlPickerButtonByName(linkName: string) { - await this.page.locator('[name="' + linkName + '"]').getByLabel('Edit').click(); + await this.click(this.page.locator(`[name="${linkName}"]`).getByLabel('Edit')); } // Upload async clickRemoveFilesButton() { - await expect(this.removeFilesBtn).toBeVisible(); - await this.removeFilesBtn.click(); + await this.click(this.removeFilesBtn); } // True/false async clickToggleButton() { - await expect(this.toggleBtn).toBeVisible(); - await this.toggleBtn.click({force: true}); + await this.click(this.toggleBtn, {force: true}); } async doesToggleHaveLabel(label: string) { - return await expect(this.toggleInput).toHaveText(label); + await this.hasText(this.toggleInput, label); } // Multiple Text String async clickAddMultipleTextStringButton() { - await this.addMultipleTextStringBtn.click(); + await this.click(this.addMultipleTextStringBtn); } async enterMultipleTextStringValue(value: string) { - await this.multipleTextStringValueTxt.clear(); - await this.multipleTextStringValueTxt.fill(value); + await this.enterText(this.multipleTextStringValueTxt, value); } async addMultipleTextStringItem(value: string) { @@ -859,83 +835,77 @@ export class ContentUiHelper extends UiBaseLocators { } async isDocumentTypeNameVisible(contentName: string, isVisible: boolean = true) { - return expect(this.sidebarModal.getByText(contentName)).toBeVisible({visible: isVisible}); + return await this.isVisible(this.sidebarModal.getByText(contentName), isVisible); } async doesModalHaveText(text: string) { - return expect(this.openedModal).toContainText(text); + await this.containsText(this.openedModal, text); } // Collection tab async isTabNameVisible(tabName: string) { - return expect(this.tabItems.filter({hasText: tabName})).toBeVisible(); + return await this.isVisible(this.tabItems.filter({hasText: tabName})); } async clickTabWithName(tabName: string) { const tabLocator = this.tabItems.filter({hasText: tabName}); - await expect(tabLocator).toBeVisible(); - await tabLocator.click(); + await this.click(tabLocator); } async doesDocumentHaveName(name: string) { - return expect(this.enterAName).toHaveValue(name); + await this.hasValue(this.enterAName, name); } async doesDocumentTableColumnNameValuesMatch(expectedValues: string[]) { - await expect(this.documentListView).toBeVisible(); + await this.waitForVisible(this.documentListView); return expectedValues.forEach((text, index) => { expect(this.documentTableColumnName.nth(index)).toHaveText(text); }); } async searchByKeywordInCollection(keyword: string) { - await this.searchTxt.clear(); - await this.searchTxt.fill(keyword); - await this.searchTxt.press('Enter'); - await this.page.waitForTimeout(500); + await this.enterText(this.searchTxt, keyword); + await this.pressKey(this.searchTxt, 'Enter'); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickSelectVariantButton() { - await expect(this.selectAVariantBtn).toBeVisible(); - await this.selectAVariantBtn.click(); + await this.click(this.selectAVariantBtn); } async clickVariantAddModeButtonForLanguageName(language: string) { - await this.variantAddModeBtn.getByText(language).click(); - await this.page.waitForTimeout(500); + await this.click(this.variantAddModeBtn.getByText(language)); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickSaveAndCloseButton() { - await this.saveAndCloseBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.saveAndCloseBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } // List View async clickCreateContentWithName(name: string) { - await expect(this.page.getByLabel('Create ' + name)).toBeVisible(); - await this.page.getByLabel('Create ' + name).click(); + await this.click(this.page.getByLabel(`Create ${name}`)); } async enterNameInContainer(name: string) { - await expect(this.enterNameInContainerTxt).toBeVisible(); - await this.enterNameInContainerTxt.clear(); - await this.enterNameInContainerTxt.fill(name); + await this.enterText(this.enterNameInContainerTxt, name); } async goToContentInListViewWithName(contentName: string) { - await this.listView.getByLabel(contentName).click(); + await this.click(this.listView.getByLabel(contentName)); } async doesListViewHaveNoItemsInList() { - await expect(this.listView.filter({hasText: 'There are no items to show in the list.'})).toBeVisible(); + await this.isVisible(this.listView.filter({hasText: 'There are no items to show in the list.'})); } async doesContentListHaveNoItemsInList() { - await expect(this.umbDocumentCollection.filter({hasText: 'No items'})).toBeVisible(); + await this.isVisible(this.umbDocumentCollection.filter({hasText: 'No items'})); } async clickNameButtonInListView() { - await this.nameBtn.click(); + await this.click(this.nameBtn); } async doesFirstItemInListViewHaveName(name: string) { @@ -943,82 +913,73 @@ export class ContentUiHelper extends UiBaseLocators { } async doesListViewContainCount(count: number) { - await expect(this.listViewTableRow).toHaveCount(count); + await this.hasCount(this.listViewTableRow, count); } async selectContentWithNameInListView(name: string) { - const contentInListViewLocator = this.listViewTableRow.filter({hasText: name}); - await expect(contentInListViewLocator).toBeVisible(); - await contentInListViewLocator.click(); + await this.click(this.listViewTableRow.filter({hasText: name})); } async clickPublishSelectedListItems() { - await this.publishSelectedListItems.click(); + await this.click(this.publishSelectedListItems); } async clickUnpublishSelectedListItems() { - await this.unpublishSelectedListItems.click(); + await this.click(this.unpublishSelectedListItems); } async clickDuplicateToSelectedListItems() { - await expect(this.duplicateToSelectedListItems).toBeVisible(); - // This force click is needed - await this.duplicateToSelectedListItems.click({force: true}); + // Force click is needed + await this.click(this.duplicateToSelectedListItems, {force: true}); } async clickMoveToSelectedListItems() { - await expect(this.moveToSelectedListItems).toBeVisible(); - // This force click is needed - await this.moveToSelectedListItems.click({force: true}); + // Force click is needed + await this.click(this.moveToSelectedListItems, {force: true}); } async clickTrashSelectedListItems() { - await this.trashSelectedListItems.click(); + await this.click(this.trashSelectedListItems); } async selectDocumentWithNameAtRoot(name: string) { await this.openCaretButtonForName('Content'); - const documentWithNameLocator = this.modalContent.getByLabel(name); - await expect(documentWithNameLocator).toBeVisible(); - await documentWithNameLocator.click(); + await this.click(this.modalContent.getByLabel(name)); await this.clickChooseButton(); } async clickTrashButton() { - await expect(this.trashBtn).toBeVisible(); - await this.trashBtn.click(); + await this.click(this.trashBtn); } async clickExactTrashButton() { - await this.exactTrashBtn.click(); + await this.click(this.exactTrashBtn); } async isDocumentListViewVisible(isVisible: boolean = true) { - await expect(this.documentListView).toBeVisible({visible: isVisible}); + await this.isVisible(this.documentListView, isVisible); } async isDocumentGridViewVisible(isVisible: boolean = true) { - await expect(this.documentGridView).toBeVisible({visible: isVisible}); + await this.isVisible(this.documentGridView, isVisible); } async changeDocumentSectionLanguage(newLanguageName: string) { - await this.documentLanguageSelect.click(); - const documentSectionLanguageLocator = this.documentLanguageSelectPopover.getByText(newLanguageName); - await expect(documentSectionLanguageLocator).toBeVisible(); + await this.click(this.documentLanguageSelect); // Force click is needed - await documentSectionLanguageLocator.click({force: true}); + await this.click(this.documentLanguageSelectPopover.getByText(newLanguageName), {force: true}); } async doesDocumentSectionHaveLanguageSelected(languageName: string) { - await expect(this.documentLanguageSelect).toHaveText(languageName); + await this.hasText(this.documentLanguageSelect, languageName); } async isDocumentReadOnly(isVisible: boolean = true) { - await expect(this.documentReadOnly).toBeVisible({visible: isVisible}); + await this.isVisible(this.documentReadOnly, isVisible); } async isDocumentNameInputEditable(isEditable: boolean = true) { - await expect(this.contentNameTxt).toBeVisible(); + await this.waitForVisible(this.contentNameTxt); await expect(this.contentNameTxt).toBeEditable({editable: isEditable}); } @@ -1031,33 +992,32 @@ export class ContentUiHelper extends UiBaseLocators { } async clickEmptyRecycleBinButton() { - await this.recycleBinMenuItem.hover(); - await expect(this.emptyRecycleBinBtn).toBeVisible(); + await this.hover(this.recycleBinMenuItem); // Force click is needed - await this.emptyRecycleBinBtn.click({force: true}); + await this.click(this.emptyRecycleBinBtn, {force: true}); } async clickConfirmEmptyRecycleBinButton() { - await this.confirmEmptyRecycleBinBtn.click(); + await this.click(this.confirmEmptyRecycleBinBtn); } async isDocumentPropertyEditable(propertyName: string, isEditable: boolean = true) { const propertyLocator = this.documentWorkspace.locator(this.property).filter({hasText: propertyName}).locator('#input'); - await expect(propertyLocator).toBeVisible(); + await this.waitForVisible(propertyLocator); await expect(propertyLocator).toBeEditable({editable: isEditable}); } async doesDocumentPropertyHaveValue(propertyName: string, value: string) { const propertyLocator = this.documentWorkspace.locator(this.property).filter({hasText: propertyName}).locator('#input'); - await expect(propertyLocator).toHaveValue(value); + await this.hasValue(propertyLocator, value); } async clickContentTab() { - await this.splitView.getByRole('tab', {name: 'Content'}).click(); + await this.click(this.splitView.getByRole('tab', {name: 'Content'})); } async isDocumentTreeEmpty() { - await expect(this.documentTreeItem).toHaveCount(0); + await this.hasCount(this.documentTreeItem, 0); } async doesDocumentWorkspaceContainName(name: string) { @@ -1065,290 +1025,246 @@ export class ContentUiHelper extends UiBaseLocators { } async doesDocumentWorkspaceHaveText(text: string) { - return expect(this.documentWorkspace).toContainText(text); + await this.containsText(this.documentWorkspace, text); } async enterDocumentBlueprintName(name: string) { - await this.documentBlueprintModalEnterNameTxt.clear(); - await this.documentBlueprintModalEnterNameTxt.fill(name); + await this.enterText(this.documentBlueprintModalEnterNameTxt, name); } async clickSaveDocumentBlueprintButton() { - await this.documentBlueprintSaveBtn.click(); + await this.click(this.documentBlueprintSaveBtn); } async clickDuplicateToButton() { - await this.duplicateToBtn.click(); + await this.click(this.duplicateToBtn); } async clickDuplicateButton() { - await this.duplicateBtn.click(); + await this.click(this.duplicateBtn); } async clickMoveToButton() { - await this.moveToBtn.click(); + await this.click(this.moveToBtn); } async moveToContentWithName(parentNames: string[], moveTo: string) { for (const contentName of parentNames) { - await this.container.getByLabel('Expand child items for ' + contentName).click(); + await this.click(this.container.getByLabel(`Expand child items for ${contentName}`)); } - await this.container.getByLabel(moveTo).click(); + await this.click(this.container.getByLabel(moveTo)); await this.clickChooseContainerButton(); } async isCaretButtonVisibleForContentName(contentName: string, isVisible: boolean = true) { - await expect(this.page.locator('[label="' + contentName + '"]').getByLabel('Expand child items for ')).toBeVisible({visible: isVisible}); + await this.isVisible(this.page.locator(`[label="${contentName}"]`).getByLabel('Expand child items for '), isVisible); } async reloadContentTree() { - await expect(this.contentTreeRefreshBtn).toBeVisible(); // Force click is needed - await this.contentTreeRefreshBtn.click({force: true}); + await this.click(this.contentTreeRefreshBtn, {force: true}); } async clickSortChildrenButton() { - await expect(this.sortChildrenBtn).toBeVisible(); - await this.sortChildrenBtn.click(); + await this.click(this.sortChildrenBtn); } async clickRollbackButton() { - await expect(this.rollbackBtn).toBeVisible(); - await this.rollbackBtn.click(); + await this.click(this.rollbackBtn); } async clickRollbackContainerButton() { - await expect(this.rollbackContainerBtn).toBeVisible(); - await this.rollbackContainerBtn.click(); + await this.click(this.rollbackContainerBtn); } async clickLatestRollBackItem() { - await expect(this.rollbackItem.last()).toBeVisible(); - await this.rollbackItem.last().click(); + await this.click(this.rollbackItem.last()); } async clickPublicAccessButton() { - await expect(this.publicAccessBtn).toBeVisible(); - await this.publicAccessBtn.click(); + await this.click(this.publicAccessBtn); } async addGroupBasedPublicAccess(memberGroupName: string, documentName: string) { - await expect(this.groupBasedProtectionBtn).toBeVisible(); - await this.groupBasedProtectionBtn.click(); + await this.click(this.groupBasedProtectionBtn); await this.clickNextButton(); - await this.chooseMemberGroupBtn.click(); - await this.page.getByLabel(memberGroupName).click(); + await this.click(this.chooseMemberGroupBtn); + await this.click(this.page.getByLabel(memberGroupName)); await this.clickChooseModalButton(); - await this.selectLoginPageDocument.click(); - await this.container.getByLabel(documentName, {exact: true}).click(); + await this.click(this.selectLoginPageDocument); + await this.click(this.container.getByLabel(documentName, {exact: true})); await this.clickChooseModalButton(); - await this.selectErrorPageDocument.click(); - await this.container.getByLabel(documentName, {exact: true}).click(); + await this.click(this.selectErrorPageDocument); + await this.click(this.container.getByLabel(documentName, {exact: true})); await this.clickChooseModalButton(); - await this.containerSaveBtn.click(); + await this.click(this.containerSaveBtn); } async sortChildrenDragAndDrop(dragFromSelector: Locator, dragToSelector: Locator, verticalOffset: number = 0, horizontalOffset: number = 0, steps: number = 5) { - await expect(dragFromSelector).toBeVisible(); - await expect(dragToSelector).toBeVisible(); + await this.waitForVisible(dragFromSelector); + await this.waitForVisible(dragToSelector); const targetLocation = await dragToSelector.boundingBox(); const elementCenterX = targetLocation!.x + targetLocation!.width / 2; const elementCenterY = targetLocation!.y + targetLocation!.height / 2; - await dragFromSelector.hover(); + await this.hover(dragFromSelector); await this.page.mouse.move(10, 10); - await dragFromSelector.hover(); + await this.hover(dragFromSelector); await this.page.mouse.down(); - await this.page.waitForTimeout(400); + await this.page.waitForTimeout(ConstantHelper.wait.debounce); await this.page.mouse.move(elementCenterX + horizontalOffset, elementCenterY + verticalOffset, {steps: steps}); - await this.page.waitForTimeout(400); + await this.page.waitForTimeout(ConstantHelper.wait.debounce); // If we do not have this, the drag and drop will not work - await dragToSelector.hover(); + await this.hover(dragToSelector); await this.page.mouse.up(); } async clickSortButton() { - await expect(this.sortBtn).toBeVisible(); - await this.sortBtn.click(); + await this.click(this.sortBtn); } async doesIndexDocumentInTreeContainName(parentName: string, childName: string, index: number) { - await expect(this.documentTreeItem.locator('[label="' + parentName + '"]').locator('umb-tree-item').nth(index).locator('#label')).toHaveText(childName); + await expect(this.documentTreeItem.locator(`[label="${parentName}"]`).locator('umb-tree-item').nth(index).locator('#label')).toHaveText(childName); } async selectMemberGroup(memberGroupName: string) { - await expect(this.uuiCheckbox.getByLabel(memberGroupName)).toBeVisible(); - await this.uuiCheckbox.getByLabel(memberGroupName).click(); + await this.click(this.uuiCheckbox.getByLabel(memberGroupName)); } async isPermissionInActionsMenuVisible(permissionName: string, isVisible: boolean = true) { - await expect(this.actionsMenu.getByRole('button', { + await this.isVisible(this.actionsMenu.getByRole('button', { name: permissionName, exact: true - })).toBeVisible({visible: isVisible}); + }), isVisible); } async clickDocumentLinkButton() { - await expect(this.linkToDocumentBtn).toBeVisible(); - await this.linkToDocumentBtn.click(); + await this.click(this.linkToDocumentBtn); } async clickMediaLinkButton() { - await expect(this.linkToMediaBtn).toBeVisible(); - await this.linkToMediaBtn.click(); + await this.click(this.linkToMediaBtn); } async clickManualLinkButton() { - await expect(this.linkToManualBtn).toBeVisible(); - await this.linkToManualBtn.click(); + await this.click(this.linkToManualBtn); } // Block Grid - Block List async clickAddBlockElementButton() { - await expect(this.addBlockElementBtn).toBeVisible(); - await this.addBlockElementBtn.click(); + await this.click(this.addBlockElementBtn); } async clickAddBlockWithNameButton(name: string) { - await expect(this.page.getByLabel('Add '+ name)).toBeVisible(); - await this.page.getByLabel('Add '+ name).click(); + await this.click(this.page.getByLabel(`Add ${name}`)); } - + async clickCreateForModalWithHeadline(headline: string) { - await expect(this.page.locator('[headline="' + headline + '"]').getByLabel('Create')).toBeVisible(); - await this.page.locator('[headline="' + headline + '"]').getByLabel('Create').click(); + await this.click(this.page.locator(`[headline="${headline}"]`).getByLabel('Create')); } async isAddBlockElementButtonVisible(isVisible: boolean = true) { - await expect(this.addBlockElementBtn).toBeVisible({visible: isVisible}); + await this.isVisible(this.addBlockElementBtn, isVisible); } async isAddBlockElementButtonWithLabelVisible(blockName: string, label: string, isVisible: boolean = true) { - await expect(this.property.filter({hasText: blockName}).locator(this.addBlockElementBtn).filter({hasText: label})).toBeVisible({visible: isVisible}); + await this.isVisible(this.property.filter({hasText: blockName}).locator(this.addBlockElementBtn).filter({hasText: label}), isVisible); } async doesFormValidationMessageContainText(text: string) { - await expect(this.formValidationMessage).toContainText(text); + await this.containsText(this.formValidationMessage, text); } async doesBlockElementHaveName(name: string) { - await expect(this.blockName).toContainText(name); + await this.containsText(this.blockName, name); } async clickAddBlockSettingsTabButton() { - await expect(this.addBlockSettingsTabBtn).toBeVisible(); - await this.addBlockSettingsTabBtn.click(); + await this.click(this.addBlockSettingsTabBtn); } async clickEditBlockGridBlockButton() { - await expect(this.blockGridEntry).toBeVisible(); - await this.blockGridEntry.hover(); - await expect(this.editBlockEntryBtn).toBeVisible(); - await this.editBlockEntryBtn.click(); + await this.hoverAndClick(this.blockGridEntry, this.editBlockEntryBtn); } async clickDeleteBlockGridBlockButton() { - await expect(this.blockGridEntry).toBeVisible(); - await this.blockGridEntry.hover(); - await expect(this.deleteBlockEntryBtn).toBeVisible(); - await this.deleteBlockEntryBtn.click(); + await this.hoverAndClick(this.blockGridEntry, this.deleteBlockEntryBtn); } async clickEditBlockListBlockButton() { - await expect(this.blockListEntry).toBeVisible(); - await this.blockListEntry.hover(); - await expect(this.editBlockEntryBtn).toBeVisible(); - await this.editBlockEntryBtn.click(); + await this.hoverAndClick(this.blockListEntry, this.editBlockEntryBtn); } async clickDeleteBlockListBlockButton() { - await expect(this.blockListEntry).toBeVisible(); - await this.blockListEntry.hover(); - await expect(this.deleteBlockEntryBtn).toBeVisible(); - await this.deleteBlockEntryBtn.click(); + await this.hoverAndClick(this.blockListEntry, this.deleteBlockEntryBtn); } async clickCopyBlockListBlockButton(groupName: string, propertyName: string, blockName: string, index: number = 0) { const blockListBlock = this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}).locator(this.blockListEntry).nth(index).filter({hasText: blockName}); - await blockListBlock.hover(); - await expect(blockListBlock.locator(this.copyBlockEntryBtn)).toBeVisible(); - await blockListBlock.locator(this.copyBlockEntryBtn).click({force: true}); - await this.page.waitForTimeout(500); + await this.hoverAndClick(blockListBlock, blockListBlock.locator(this.copyBlockEntryBtn), {force: true}); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickCopyBlockGridBlockButton(groupName: string, propertyName: string, blockName: string, index: number = 0) { const blockGridBlock = this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}).locator(this.blockGridEntry).nth(index).filter({hasText: blockName}); - await blockGridBlock.hover(); - await expect(blockGridBlock.locator(this.copyBlockEntryBtn)).toBeVisible(); - await blockGridBlock.locator(this.copyBlockEntryBtn).click({force: true}); - await this.page.waitForTimeout(500); + await this.hoverAndClick(blockGridBlock, blockGridBlock.locator(this.copyBlockEntryBtn), {force: true}); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickPasteFromClipboardButtonForProperty(groupName: string, propertyName: string) { - await this.page.waitForTimeout(500); + await this.page.waitForTimeout(ConstantHelper.wait.short); const property = this.workspaceEditTab.filter({hasText: groupName}).locator(this.property).filter({hasText: propertyName}); - await expect(property).toBeVisible(); - await expect(property.locator(this.pasteFromClipboardBtn)).toBeVisible(); - await property.locator(this.pasteFromClipboardBtn).click({force: true}); + await this.click(property.locator(this.pasteFromClipboardBtn), {force: true}); } async clickActionsMenuForProperty(groupName: string, propertyName: string) { const property = this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}); - await property.hover(); - await expect(property.locator(this.openActionsMenu)).toBeVisible(); - await property.locator(this.openActionsMenu).click({force: true}); + await this.hoverAndClick(property, property.locator(this.openActionsMenu), {force: true}); } async clickAddBlockGridElementWithName(elementTypeName: string) { - await expect(this.page.getByRole('link', {name: 'Add ' + elementTypeName, exact: true})).toBeVisible(); - await this.page.getByRole('link', {name: 'Add ' + elementTypeName, exact: true}).click(); + await this.click(this.page.getByRole('link', {name: `Add ${elementTypeName}`, exact: true})); } async clickEditBlockListEntryWithName(blockListElementName: string) { - await expect(this.blockListEntry.filter({hasText: blockListElementName}).getByLabel('edit')).toBeVisible(); - await this.blockListEntry.filter({hasText: blockListElementName}).getByLabel('edit').click({force: true}); + await this.click(this.blockListEntry.filter({hasText: blockListElementName}).getByLabel('edit'), {force: true}); } async clickSelectBlockElementWithName(elementTypeName: string) { - await expect(this.page.getByRole('button', {name: elementTypeName, exact: true})).toBeVisible(); - await this.page.getByRole('button', {name: elementTypeName, exact: true}).click(); + await this.click(this.page.getByRole('button', {name: elementTypeName, exact: true})); } async clickSelectBlockElementInAreaWithName(elementTypeName: string) { - await expect(this.container.getByRole('button', {name: elementTypeName, exact: true})).toBeVisible(); - await this.container.getByRole('button', {name: elementTypeName, exact: true}).click(); + await this.click(this.container.getByRole('button', {name: elementTypeName, exact: true})); } async clickBlockElementWithName(elementTypeName: string) { - await expect(this.page.getByRole('link', {name: elementTypeName, exact: true})).toBeVisible(); - await this.page.getByRole('link', {name: elementTypeName, exact: true}).click({force: true}); + await this.click(this.page.getByRole('link', {name: elementTypeName, exact: true}), {force: true}); } async enterPropertyValue(propertyName: string, value: string) { const property = this.property.filter({hasText: propertyName}); - await expect(property).toBeVisible(); - await property.locator('input').clear(); - await property.locator('input').fill(value); + await this.enterText(property.locator('input'), value); } async doesBlockContainBlockInAreaWithName(blockWithAreaName: string, areaName: string, blockInAreaName: string, index: number = 0) { const blockWithArea = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: blockWithAreaName})).nth(index); - const area = blockWithArea.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); + const area = blockWithArea.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); const blockInArea = area.locator(this.blockGridEntry.filter({hasText: blockInAreaName})); - await expect(blockInArea).toBeVisible(); + await this.waitForVisible(blockInArea); } async doesBlockContainBlockCountInArea(blockWithAreaName: string, areaName: string, blocksInAreaCount: number, index: number = 0) { const blockWithArea = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: blockWithAreaName})).nth(index); - const area = blockWithArea.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); + const area = blockWithArea.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); const blocks = area.locator(this.blockGridEntry); - await expect(blocks).toHaveCount(blocksInAreaCount); + await this.hasCount(blocks, blocksInAreaCount); } async doesBlockContainCountOfBlockInArea(blockWithAreaName: string, areaName: string, blockInAreaName: string, count: number, index: number = 0) { const blockWithArea = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: blockWithAreaName})).nth(index); - const area = blockWithArea.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); + const area = blockWithArea.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); const blockInArea = area.locator(this.blockGridEntry.filter({hasText: blockInAreaName})); - await expect(blockInArea).toHaveCount(count); + await this.hasCount(blockInArea, count); } async getBlockAtRootDataElementKey(blockName: string, index: number = 0) { @@ -1363,50 +1279,48 @@ export class ContentUiHelper extends UiBaseLocators { async getBlockDataElementKeyInArea(parentBlockName: string, areaName: string, blockName: string, parentIndex: number = 0, childIndex: number = 0) { const parentBlock = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: parentBlockName})).nth(parentIndex); - const area = parentBlock.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); + const area = parentBlock.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); const block = area.locator(this.blockGridEntry.filter({hasText: blockName})).nth(childIndex); return block.getAttribute('data-element-key'); } async removeBlockFromArea(parentBlockName: string, areaName: string, blockName: string, parentIndex: number = 0, childIndex: number = 0) { const parentBlock = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: parentBlockName})).nth(parentIndex); - const area = parentBlock.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); + const area = parentBlock.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); const block = area.locator(this.blockGridEntry.filter({hasText: blockName})).nth(childIndex); - await block.hover(); - await block.getByLabel('delete').click({force: true}); + await this.hoverAndClick(block, block.getByLabel('delete'), {force: true}); } async doesBlockAreaContainColumnSpan(blockWithAreaName: string, areaName: string, columnSpan: number, index: number = 0) { const blockWithArea = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: blockWithAreaName})).nth(index); - const area = blockWithArea.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); - await expect(area).toHaveAttribute('data-area-col-span', columnSpan.toString()); + const area = blockWithArea.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); + await this.hasAttribute(area, 'data-area-col-span', columnSpan.toString()); } async doesBlockAreaContainRowSpan(blockWithAreaName: string, areaName: string, rowSpan: number, index: number = 0) { const blockWithArea = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: blockWithAreaName})).nth(index); - const area = blockWithArea.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); - await expect(area).toHaveAttribute('data-area-row-span', rowSpan.toString()); + const area = blockWithArea.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); + await this.hasAttribute(area, 'data-area-row-span', rowSpan.toString()); } async clickInlineAddToAreaButton(parentBlockName: string, areaName: string, parentIndex: number = 0, buttonIndex: number = 1) { const parentBlock = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: parentBlockName})).nth(parentIndex); - const area = parentBlock.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); - await area.locator(this.inlineCreateBtn).nth(buttonIndex).click(); + const area = parentBlock.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); + await this.click(area.locator(this.inlineCreateBtn).nth(buttonIndex)); } async addBlockToAreasWithExistingBlock(blockWithAreaName: string, areaName: string, parentIndex: number = 0, addToIndex: number = 0) { const blockWithArea = this.blockGridEntry.locator(this.blockGridBlock).filter({hasText: blockWithAreaName}).nth(parentIndex); - await expect(blockWithArea).toBeVisible(); - await blockWithArea.hover(); - const area = blockWithArea.locator(this.blockGridAreasContainer).locator('[data-area-alias="' + areaName + '"]'); + await this.hover(blockWithArea); + const area = blockWithArea.locator(this.blockGridAreasContainer).locator(`[data-area-alias="${areaName}"]`); const addBlockBtn = area.locator(this.inlineCreateBtn).nth(addToIndex); - await addBlockBtn.hover({force: true}); - await addBlockBtn.click({force: true}); + await this.hover(addBlockBtn, {force: true}); + await this.click(addBlockBtn, {force: true}); } async doesBlockGridBlockWithAreaContainCreateLabel(blockWithAreaName: string, createLabel: string, index: number = 0) { const blockWithArea = this.blockGridEntry.locator(this.blockGridBlock.filter({hasText: blockWithAreaName})).nth(index); - return expect(blockWithArea.locator(this.blockGridAreasContainer).getByLabel(createLabel)).toBeVisible(); + return await this.isVisible(blockWithArea.locator(this.blockGridAreasContainer).getByLabel(createLabel)); } async doesPropertyContainValue(propertyName: string, value: string) { @@ -1414,57 +1328,51 @@ export class ContentUiHelper extends UiBaseLocators { } async clickCreateButtonForModalWithElementTypeNameAndGroupName(headlineName: string, groupName: string) { - await expect(this.blockWorkspace.filter({hasText: 'Add ' + headlineName}).filter({hasText: groupName}).getByLabel('Create')).toBeVisible(); - await this.blockWorkspace.filter({hasText: 'Add ' + headlineName}).filter({hasText: groupName}).getByLabel('Create').click(); + await this.click(this.blockWorkspace.filter({hasText: `Add ${headlineName}`}).filter({hasText: groupName}).getByLabel('Create')); } async clickUpdateButtonForModalWithElementTypeNameAndGroupName(headlineName: string, groupName: string) { - await expect(this.blockWorkspace.filter({hasText: 'Edit ' + headlineName}).filter({hasText: groupName}).locator(this.updateBtn)).toBeVisible(); - await this.blockWorkspace.filter({hasText: 'Edit ' + headlineName}).filter({hasText: groupName}).locator(this.updateBtn).click(); + await this.click(this.blockWorkspace.filter({hasText: `Edit ${headlineName}`}).filter({hasText: groupName}).locator(this.updateBtn)); } async clickExactCopyButton() { - await expect(this.exactCopyBtn).toBeVisible(); - await this.exactCopyBtn.click(); + await this.click(this.exactCopyBtn); } async clickExactReplaceButton() { - await expect(this.replaceExactBtn).toBeVisible(); - await this.replaceExactBtn.click(); + await this.click(this.replaceExactBtn); } async doesClipboardHaveCopiedBlockWithName(contentName: string, propertyName: string, blockName: string, index: number = 0) { - await expect(this.clipboardEntryPicker.getByLabel(`${contentName} - ${propertyName} - ${blockName}`).nth(index)).toBeVisible(); + await this.isVisible(this.clipboardEntryPicker.getByLabel(`${contentName} - ${propertyName} - ${blockName}`).nth(index)); } async doesClipboardHaveCopiedBlocks(contentName: string, propertyName: string, index: number = 0) { - await expect(this.clipboardEntryPicker.getByLabel(`${contentName} - ${propertyName}`).nth(index)).toBeVisible(); + await this.isVisible(this.clipboardEntryPicker.getByLabel(`${contentName} - ${propertyName}`).nth(index)); } async doesClipboardContainCopiedBlocksCount(count: number) { - await expect(this.clipboardEntryPicker.locator(this.menuItem)).toHaveCount(count); + await this.hasCount(this.clipboardEntryPicker.locator(this.menuItem), count); } async selectClipboardEntryWithName(contentName: string, propertyName: string, blockName: string, index: number = 0) { await this.doesClipboardHaveCopiedBlockWithName(contentName, propertyName, blockName, index); - await this.clipboardEntryPicker.getByLabel(`${contentName} - ${propertyName} - ${blockName}`).nth(index).click(); + await this.click(this.clipboardEntryPicker.getByLabel(`${contentName} - ${propertyName} - ${blockName}`).nth(index)); } async selectClipboardEntriesWithName(contentName: string, propertyName: string, index: number = 0) { await this.doesClipboardHaveCopiedBlocks(contentName, propertyName, index); - await this.clipboardEntryPicker.getByLabel(`${contentName} - ${propertyName}`).nth(index).click(); + await this.click(this.clipboardEntryPicker.getByLabel(`${contentName} - ${propertyName}`).nth(index)); } async goToBlockGridBlockWithName(groupName: string, propertyName: string, blockName: string, index: number = 0) { const blockGridBlock = this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}).locator(this.blockGridEntry).nth(index).filter({hasText: blockName}); - await expect(blockGridBlock).toBeVisible(); - await blockGridBlock.click(); + await this.click(blockGridBlock); } async goToBlockListBlockWithName(groupName: string, propertyName: string, blockName: string, index: number = 0) { const blocklistBlock = this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}).locator(this.blockListEntry).nth(index).filter({hasText: blockName}); - await expect(blocklistBlock).toBeVisible(); - await blocklistBlock.click(); + await this.click(blocklistBlock); } async doesBlockEditorBlockWithNameContainValue(groupName: string, propertyName: string, inputType: string = ConstantHelper.inputTypes.general, value) { @@ -1472,21 +1380,19 @@ export class ContentUiHelper extends UiBaseLocators { } async clickCloseButton() { - await expect(this.closeBtn).toBeVisible(); - await this.closeBtn.click(); + await this.click(this.closeBtn); } async clickPasteButton() { - await expect(this.pasteBtn).toBeVisible(); - await this.pasteBtn.click({force: true}); + await this.click(this.pasteBtn, {force: true}); } async doesBlockListPropertyHaveBlockAmount(groupName: string, propertyName: string, amount: number) { - await expect(this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}).locator(this.blockListEntry)).toHaveCount(amount); + await this.hasCount(this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}).locator(this.blockListEntry), amount); } async doesBlockGridPropertyHaveBlockAmount(groupName: string, propertyName: string, amount: number) { - await expect(this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}).locator(this.blockGridEntry)).toHaveCount(amount); + await this.hasCount(this.workspaceEditTab.filter({hasText: groupName}).locator(this.workspaceEditProperties).filter({hasText: propertyName}).locator(this.blockGridEntry), amount); } async doesPropertyContainValidationMessage(groupName: string, propertyName: string, message: string) { @@ -1494,52 +1400,45 @@ export class ContentUiHelper extends UiBaseLocators { } async clickInsertBlockButton() { - await expect(this.insertBlockBtn).toBeVisible(); - await this.insertBlockBtn.click(); + await this.click(this.insertBlockBtn); } // TipTap async enterRTETipTapEditor(value: string) { - await expect(this.tipTapEditor).toBeVisible(); - await this.tipTapEditor.clear(); - await this.tipTapEditor.fill(value); + await this.enterText(this.tipTapEditor, value); } - + async enterRTETipTapEditorWithName(name: string , value: string){ - const tipTapEditorLocator = this.page.locator('[data-mark="property:' + name + '"]').locator(this.tipTapEditor); - await expect(tipTapEditorLocator).toBeVisible(); - await tipTapEditorLocator.clear(); - await tipTapEditorLocator.fill(value); + const tipTapEditorLocator = this.page.locator(`[data-mark="property:${name}"]`).locator(this.tipTapEditor); + await this.enterText(tipTapEditorLocator, value); } async clickTipTapToolbarIconWithTitle(iconTitle: string) { - await expect(this.tipTapPropertyEditor.getByTitle(iconTitle, {exact: true}).locator('svg')).toBeVisible(); - await this.tipTapPropertyEditor.getByTitle(iconTitle, {exact: true}).locator('svg').click(); + await this.click(this.tipTapPropertyEditor.getByTitle(iconTitle, {exact: true}).locator('svg')); } async doesUploadedSvgThumbnailHaveSrc(imageSrc: string) { - await expect(this.uploadedSvgThumbnail).toBeVisible(); - await expect(this.uploadedSvgThumbnail).toHaveAttribute('src', imageSrc); + await this.hasAttribute(this.uploadedSvgThumbnail, 'src', imageSrc); } async doesRichTextEditorBlockContainLabel(richTextEditorAlias: string, label: string) { - await expect(this.page.getByTestId('property:' + richTextEditorAlias).locator(this.rteBlock)).toContainText(label); + await expect(this.page.getByTestId(`property:${richTextEditorAlias}`).locator(this.rteBlock)).toContainText(label); } async doesBlockEditorModalContainEditorSize(editorSize: string, elementName: string) { - await expect(this.backofficeModalContainer.locator('[size="' + editorSize + '"]').locator('[headline="Add ' + elementName + '"]')).toBeVisible(); + await this.isVisible(this.backofficeModalContainer.locator(`[size="${editorSize}"]`).locator(`[headline="Add ${elementName}"]`)); } async doesBlockEditorModalContainInline(richTextEditorAlias: string, elementName: string) { - await expect(this.page.getByTestId('property:' + richTextEditorAlias).locator(this.tiptapInput).locator(this.rteBlockInline)).toContainText(elementName); + await this.containsText(this.page.getByTestId(`property:${richTextEditorAlias}`).locator(this.tiptapInput).locator(this.rteBlockInline), elementName); } async doesBlockHaveBackgroundColor(elementName: string, backgroundColor: string) { - await expect(this.page.locator('umb-block-type-card', {hasText: elementName}).locator('[style="background-color:' + backgroundColor + ';"]')).toBeVisible(); + await this.isVisible(this.page.locator('umb-block-type-card', {hasText: elementName}).locator(`[style="background-color:${backgroundColor};"]`)); } async doesBlockHaveIconColor(elementName: string, backgroundColor: string) { - await expect(this.page.locator('umb-block-type-card', {hasText: elementName}).locator('[color="' + backgroundColor + '"]')).toBeVisible(); + await this.isVisible(this.page.locator('umb-block-type-card', {hasText: elementName}).locator(`[color="${backgroundColor}"]`)); } async addDocumentDomain(domainName: string, languageName: string) { @@ -1552,190 +1451,172 @@ export class ContentUiHelper extends UiBaseLocators { // Scheduled Publishing async clickViewMoreOptionsButton() { - await expect(this.viewMoreOptionsBtn).toBeVisible(); - await this.viewMoreOptionsBtn.click(); + await this.click(this.viewMoreOptionsBtn); } async clickSchedulePublishButton() { - await expect(this.schedulePublishBtn).toBeVisible(); - await this.schedulePublishBtn.click(); + await this.click(this.schedulePublishBtn); } async clickSchedulePublishModalButton() { - await expect(this.schedulePublishModalBtn).toBeVisible(); - await this.schedulePublishModalBtn.click(); + await this.click(this.schedulePublishModalBtn); } async enterPublishTime(time: string, index: number = 0) { const publishAtTxt = this.documentScheduleModal.locator('.publish-date').nth(index).locator('uui-form-layout-item').first().locator('#input'); - await expect(publishAtTxt).toBeVisible(); - await publishAtTxt.fill(time); + await this.enterText(publishAtTxt, time); } async enterUnpublishTime(time: string, index: number = 0) { const unpublishAtTxt = this.documentScheduleModal.locator('.publish-date').nth(index).locator('uui-form-layout-item').last().locator('#input'); - await expect(unpublishAtTxt).toBeVisible(); - await unpublishAtTxt.fill(time); + await this.enterText(unpublishAtTxt, time); } async doesPublishAtValidationMessageContainText(text: string) { - await expect(this.publishAtValidationMessage).toContainText(text); + await this.containsText(this.publishAtValidationMessage, text); } async doesUnpublishAtValidationMessageContainText(text: string) { - await expect(this.unpublishAtValidationMessage).toContainText(text); + await this.containsText(this.unpublishAtValidationMessage, text); } async doesLastPublishedContainText(text: string) { - await expect(this.lastPublished).toContainText(text); + await this.containsText(this.lastPublished, text); } async doesPublishAtContainText(text: string) { - await expect(this.publishAt).toContainText(text); + await this.containsText(this.publishAt, text); } async doesRemoveAtContainText(text: string) { - await expect(this.removeAt).toContainText(text); + await this.containsText(this.removeAt, text); } async clickSelectAllCheckbox() { - await expect(this.selectAllCheckbox).toBeVisible(); - await this.selectAllCheckbox.click(); + await this.click(this.selectAllCheckbox); } async doesSchedulePublishModalButtonContainDisabledTag(hasDisabledTag: boolean = false) { if (!hasDisabledTag) { - return await expect(this.schedulePublishModalBtn).not.toHaveAttribute('disabled', ''); + await expect(this.schedulePublishModalBtn).not.toHaveAttribute('disabled', ''); + } else { + await this.hasAttribute(this.schedulePublishModalBtn, 'disabled', ''); } - return await expect(this.schedulePublishModalBtn).toHaveAttribute('disabled', ''); } async clickInlineBlockCaretButtonForName(blockEditorName: string, index: number = 0) { const caretButtonLocator = this.blockListEntry.filter({hasText: blockEditorName}).nth(index).locator('uui-symbol-expand svg'); - await expect(caretButtonLocator).toBeVisible(); - await caretButtonLocator.click(); + await this.click(caretButtonLocator); } - + async doesTiptapHaveWordCount(count: number) { - await expect(this.tiptapStatusbarWordCount).toHaveText(count.toString() + ' words'); + await this.hasText(this.tiptapStatusbarWordCount, `${count} words`); } - - async doesTiptapHaveCharacterCount(count: number) { - await expect(this.tiptapStatusbarWordCount).toHaveText(count.toString() + ' characters'); + + async doesTiptapHaveCharacterCount(count: number) { + await this.hasText(this.tiptapStatusbarWordCount, `${count} characters`); } async clickTiptapWordCountButton() { - await expect(this.tiptapStatusbarWordCount).toBeVisible(); - await this.tiptapStatusbarWordCount.click(); + await this.click(this.tiptapStatusbarWordCount); } async doesElementPathHaveText(text: string) { - await expect(this.tiptapStatusbarElementPath).toHaveText(text); + await this.hasText(this.tiptapStatusbarElementPath, text); } async clickConfirmToPublishButton() { - await this.confirmToPublishBtn.click(); + await this.click(this.confirmToPublishBtn); + // Extra wait to ensure publish process starts + await this.waitForTimeout(ConstantHelper.wait.medium); } async clickPublishWithDescendantsButton() { - await expect(this.publishWithDescendantsBtn).toBeVisible(); - await this.publishWithDescendantsBtn.click(); + await this.click(this.publishWithDescendantsBtn); } async clickIncludeUnpublishedDescendantsToggle() { - await expect(this.includeUnpublishedDescendantsToggle).toBeVisible(); - await this.includeUnpublishedDescendantsToggle.click(); + await this.click(this.includeUnpublishedDescendantsToggle); } async clickPublishWithDescendantsModalButton() { - await expect(this.publishWithDescendantsModalBtn).toBeVisible(); - await this.publishWithDescendantsModalBtn.click(); + await this.click(this.publishWithDescendantsModalBtn); } async doesDocumentVariantLanguageItemHaveCount(count: number) { - await expect(this.documentVariantLanguageItem).toHaveCount(count); + await this.hasCount(this.documentVariantLanguageItem, count); } async doesDocumentVariantLanguageItemHaveName(name: string) { - await expect(this.documentVariantLanguagePicker).toContainText(name); + await this.containsText(this.documentVariantLanguagePicker, name); } async clickSchedulePublishLanguageButton(languageName: string) { - await expect(this.page.getByRole('menu').filter({hasText: languageName})).toBeVisible(); - await this.page.getByRole('menu').filter({hasText: languageName}).click(); + await this.click(this.page.getByRole('menu').filter({hasText: languageName})); } async clickBlockCardWithName(name: string, toForce: boolean = false) { const blockWithNameLocator = this.page.locator('uui-card-block-type', {hasText: name}); - await expect(blockWithNameLocator).toBeVisible(); - await blockWithNameLocator.click({force: toForce}); + await this.click(blockWithNameLocator, {force: toForce}); } async clickStyleSelectButton() { - await expect(this.styleSelectBtn).toBeVisible(); - await this.styleSelectBtn.click(); + await this.click(this.styleSelectBtn); } async clickCascadingMenuItemWithName(name: string) { - const menuItemLocator = this.cascadingMenuContainer.locator('uui-menu-item[label="' + name + '"]'); - await expect(menuItemLocator).toBeVisible(); - await menuItemLocator.click(); + const menuItemLocator = this.cascadingMenuContainer.locator(`uui-menu-item[label="${name}"]`); + await this.click(menuItemLocator); } async hoverCascadingMenuItemWithName(name: string) { - const menuItemLocator = this.cascadingMenuContainer.locator('uui-menu-item[label="' + name + '"]'); - await expect(menuItemLocator).toBeVisible(); - await menuItemLocator.hover(); + const menuItemLocator = this.cascadingMenuContainer.locator(`uui-menu-item[label="${name}"]`); + await this.hover(menuItemLocator); } async selectAllRTETipTapEditorText() { - await expect(this.tipTapEditor).toBeVisible(); - await this.tipTapEditor.click(); - await this.page.keyboard.press('Control+A'); + await this.click(this.tipTapEditor); + await this.pressKey(this.tipTapEditor, 'Control+A'); } async waitForContentToBePublished() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForRecycleBinToBeEmptied() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async clearTipTapEditor() { - await expect(this.tipTapEditor).toBeVisible(); + await this.waitForVisible(this.tipTapEditor); // We use the middle mouse button click so we don't accidentally open a block in the RTE. This solution avoids that. await this.tipTapEditor.click({button: "middle"}); - await this.page.keyboard.press('Control+A'); - await this.page.keyboard.press('Backspace'); + await this.pressKey(this.tipTapEditor, 'Control+A'); + await this.pressKey(this.tipTapEditor, 'Backspace'); } async clickBlockElementInRTEWithName(elementTypeName: string) { const blockElementLocator = this.page.locator('uui-ref-node umb-ufm-render').filter({hasText: elementTypeName}); - await expect(blockElementLocator).toBeVisible(); - await blockElementLocator.click({force: true}); + await this.click(blockElementLocator, {force: true}); } async doesModalFormValidationMessageContainText(text: string) { - await expect(this.modalFormValidationMessage).toContainText(text); + await this.containsText(this.modalFormValidationMessage, text); } async enterSearchKeywordInTreePickerModal(keyword: string) { - await expect(this.treePickerSearchTxt).toBeVisible(); - await this.treePickerSearchTxt.fill(keyword); - await this.page.keyboard.press('Enter'); + await this.enterText(this.treePickerSearchTxt, keyword); + await this.pressKey(this.treePickerSearchTxt, 'Enter'); } async enterSearchKeywordInMediaPickerModal(keyword: string) { - await expect(this.mediaPickerSearchTxt).toBeVisible(); - await this.mediaPickerSearchTxt.fill(keyword); - await this.page.keyboard.press('Enter'); + await this.enterText(this.mediaPickerSearchTxt, keyword); + await this.pressKey(this.mediaPickerSearchTxt, 'Enter'); } async enterSearchKeywordInMemberPickerModal(keyword: string) { - await expect(this.memberPickerSearchTxt).toBeVisible(); - await this.memberPickerSearchTxt.fill(keyword); - await this.page.keyboard.press('Enter'); + await this.enterText(this.memberPickerSearchTxt, keyword); + await this.pressKey(this.memberPickerSearchTxt, 'Enter'); } async isContentNameReadOnly() { @@ -1744,7 +1625,7 @@ export class ContentUiHelper extends UiBaseLocators { // Block Custom View async isBlockCustomViewVisible(blockCustomViewLocator: string, isVisible: boolean = true) { - await expect(this.page.locator(blockCustomViewLocator)).toBeVisible({visible: isVisible}); + await this.isVisible(this.page.locator(blockCustomViewLocator), isVisible); } async isSingleBlockElementVisible(isVisible: boolean = true) { @@ -1754,36 +1635,34 @@ export class ContentUiHelper extends UiBaseLocators { } else { expect(count, `Expected only one element, but found ${count}`).toBe(0); } - await expect(this.refListBlock).toBeVisible({visible: isVisible}); + await this.isVisible(this.refListBlock, isVisible); } async doesBlockCustomViewHaveValue(customBlockViewLocator: string, valueText: string) { const locator = this.page.locator(`${customBlockViewLocator} p`); - await expect(locator).toBeVisible(); - await expect(locator).toHaveText(valueText); + await this.waitForVisible(locator); + await this.hasText(locator, valueText); } - + async clickPropertyActionWithName(name: string) { - const actionLocator = this.propertyActionMenu.locator('umb-property-action uui-menu-item[label="' + name + '"]'); - await expect(actionLocator).toBeVisible(); - await actionLocator.click(); + const actionLocator = this.propertyActionMenu.locator(`umb-property-action uui-menu-item[label="${name}"]`); + await this.click(actionLocator); } async isContentWithNameVisibleInList(contentName: string, isVisible: boolean = true) { - await expect(this.documentTableColumnName.filter({hasText: contentName})).toBeVisible({visible: isVisible}); + await this.isVisible(this.documentTableColumnName.filter({hasText: contentName}), isVisible); } async selectDocumentBlueprintWithName(blueprintName: string) { - await expect(this.documentCreateOptionsModal.locator('uui-menu-item', {hasText: blueprintName})).toBeVisible(); - await this.documentCreateOptionsModal.locator('uui-menu-item', {hasText: blueprintName}).click(); + await this.click(this.documentCreateOptionsModal.locator('uui-menu-item', {hasText: blueprintName})); } async doesDocumentModalHaveText(text: string) { - await expect(this.documentCreateOptionsModal).toContainText(text); + await this.containsText(this.documentCreateOptionsModal, text); } async doesListViewItemsHaveCount(pageSize: number){ - await expect(this.listViewCustomRows).toHaveCount(pageSize); + await this.hasCount(this.listViewCustomRows, pageSize); } async isListViewItemWithNameVisible(itemName: string, index: number = 0){ @@ -1791,95 +1670,86 @@ export class ContentUiHelper extends UiBaseLocators { } async clickPaginationNextButton(){ - await expect(this.nextPaginationBtn).toBeVisible(); - await this.nextPaginationBtn.click(); + await this.click(this.nextPaginationBtn); } - + // Entity Data Picker async chooseCollectionMenuItemWithName(name: string) { await this.clickChooseButton(); - await this.collectionMenu.locator('umb-collection-menu-item', {hasText: name}).click(); + await this.click(this.collectionMenu.locator('umb-collection-menu-item', {hasText: name})); await this.clickChooseContainerButton(); } - + async chooseTreeMenuItemWithName(name: string, parentNames: string[] = []) { await this.clickChooseButton(); for (const itemName of parentNames) { - await this.entityPickerTree.locator('umb-tree-item').getByLabel('Expand child items for ' + itemName).click(); + await this.click(this.entityPickerTree.locator('umb-tree-item').getByLabel(`Expand child items for ${itemName}`)); } - await this.container.getByLabel(name).click(); + await this.click(this.container.getByLabel(name)); await this.clickChooseContainerButton(); } async isChooseButtonVisible(isVisible: boolean = true) { - await expect(this.chooseBtn).toBeVisible({visible: isVisible}); + await this.isVisible(this.chooseBtn, isVisible); } async clickDocumentNotificationOptionWithName(name: string) { - const notificationOptionLocator = this.page.locator('umb-document-notifications-modal [id$="' + name + '"]').locator('#toggle'); - await expect(notificationOptionLocator).toBeVisible(); - await notificationOptionLocator.click(); + const notificationOptionLocator = this.page.locator(`umb-document-notifications-modal [id$="${name}"]`).locator('#toggle'); + await this.click(notificationOptionLocator); } async switchLanguage(languageName: string) { - await expect(this.languageToggle).toBeVisible(); - await this.languageToggle.click(); + await this.click(this.languageToggle); const languageOptionLocator = this.contentVariantDropdown.locator('.culture-variant').filter({hasText: languageName}); - await expect(languageOptionLocator).toBeVisible(); - await languageOptionLocator.click(); + await this.click(languageOptionLocator); await expect(languageOptionLocator).toContainClass('selected'); } async clickAddBlockListElementWithName(blockName: string) { - const createNewButtonLocator = this.page.getByTestId('property:' + blockName.toLowerCase()).getByLabel('Create new'); - await expect(createNewButtonLocator).toBeVisible(); - await createNewButtonLocator.click(); + const createNewButtonLocator = this.page.getByTestId(`property:${blockName.toLowerCase()}`).getByLabel('Create new'); + await this.click(createNewButtonLocator); } async isAddBlockListElementWithNameDisabled(blockName: string) { - const createNewButtonLocator = this.page.getByTestId('property:' + blockName.toLowerCase()).locator('uui-button[label="Create new"]'); + const createNewButtonLocator = this.page.getByTestId(`property:${blockName.toLowerCase()}`).locator('uui-button[label="Create new"]'); await expect(createNewButtonLocator).toHaveAttribute('disabled'); } async isAddBlockListElementWithNameVisible(blockName: string) { - const createNewButtonLocator = this.page.getByTestId('property:' + blockName.toLowerCase()).locator('uui-button[label="Create new"]'); - await expect(createNewButtonLocator).toBeVisible(); + const createNewButtonLocator = this.page.getByTestId(`property:${blockName.toLowerCase()}`).locator('uui-button[label="Create new"]'); + await this.waitForVisible(createNewButtonLocator); await expect(createNewButtonLocator).not.toHaveAttribute('disabled'); } async enterBlockPropertyValue(propertyName: string, value: string) { const property = this.blockProperty.filter({hasText: propertyName}); - await expect(property).toBeVisible(); - await property.locator('input').clear(); - await property.locator('input').fill(value); + await this.enterText(property.locator('input'), value); } async isBlockPropertyEditable(propertyName: string, isEditable: boolean = true) { const propertyLocator = this.blockProperty.filter({hasText: propertyName}).locator('#input'); - await expect(propertyLocator).toBeVisible(); + await this.waitForVisible(propertyLocator); await expect(propertyLocator).toBeEditable({editable: isEditable}); } async isInlineBlockPropertyVisible(propertyName: string, isVisible: boolean = true) { const propertyLocator = this.blockListEntry.locator(this.blockProperty).filter({hasText: propertyName}); - await expect(propertyLocator).toBeVisible({visible: isVisible}); + await this.isVisible(propertyLocator, isVisible); } async isInlineBlockPropertyVisibleForBlockWithName(blockName: string, propertyName: string, isVisible: boolean = true, index: number = 0) { const blockEntryLocator = this.blockListEntry.filter({hasText: blockName}).nth(index); const propertyLocator = blockEntryLocator.locator(this.blockProperty).filter({hasText: propertyName}); - await expect(propertyLocator).toBeVisible({visible: isVisible}); + await this.isVisible(propertyLocator, isVisible); } async enterInlineBlockPropertyValue(propertyName: string, value: string, index: number = 0) { const propertyLocator = this.blockListEntry.nth(index).locator(this.blockProperty).filter({hasText: propertyName}); - await expect(propertyLocator).toBeVisible(); - await propertyLocator.locator('input').clear(); - await propertyLocator.locator('input').fill(value); + await this.enterText(propertyLocator.locator('input'), value); } async doesInlineBlockPropertyHaveValue(propertyName: string, value: string, index: number = 0) { const propertyLocator = this.blockListEntry.nth(index).locator(this.blockProperty).filter({hasText: propertyName}).locator('input'); - await expect(propertyLocator).toHaveValue(value); + await this.hasValue(propertyLocator, value); } } \ No newline at end of file diff --git a/lib/helpers/CurrentUserProfileUiHelper.ts b/lib/helpers/CurrentUserProfileUiHelper.ts index 2b16ac19..bdd47cd9 100644 --- a/lib/helpers/CurrentUserProfileUiHelper.ts +++ b/lib/helpers/CurrentUserProfileUiHelper.ts @@ -1,4 +1,4 @@ -import {expect, Locator, Page} from "@playwright/test" +import {Locator, Page} from "@playwright/test" import {UiBaseLocators} from "./UiBaseLocators"; export class CurrentUserProfileUiHelper extends UiBaseLocators { @@ -10,18 +10,13 @@ export class CurrentUserProfileUiHelper extends UiBaseLocators { } async clickChangePasswordButton() { - await expect(this.changePasswordBtn).toBeVisible(); - await this.changePasswordBtn.click(); + await this.click(this.changePasswordBtn); } async changePassword(currentPassword: string, newPassword: string) { - await expect(this.currentPasswordTxt).toBeVisible(); - await this.currentPasswordTxt.clear(); - await this.currentPasswordTxt.fill(currentPassword); - await this.newPasswordTxt.clear(); - await this.newPasswordTxt.fill(newPassword); - await this.confirmPasswordTxt.clear(); - await this.confirmPasswordTxt.fill(newPassword); + await this.enterText(this.currentPasswordTxt, currentPassword); + await this.enterText(this.newPasswordTxt, newPassword); + await this.enterText(this.confirmPasswordTxt, newPassword); await this.clickConfirmButton(); } } \ No newline at end of file diff --git a/lib/helpers/DataTypeUiHelper.ts b/lib/helpers/DataTypeUiHelper.ts index 39659805..6b9aca9b 100644 --- a/lib/helpers/DataTypeUiHelper.ts +++ b/lib/helpers/DataTypeUiHelper.ts @@ -1,5 +1,6 @@ import {Page, Locator, expect} from "@playwright/test"; import {UiBaseLocators} from "./UiBaseLocators"; +import {ConstantHelper} from "./ConstantHelper"; export class DataTypeUiHelper extends UiBaseLocators { private readonly moveToBtn: Locator; @@ -344,70 +345,59 @@ export class DataTypeUiHelper extends UiBaseLocators { async goToDataType(dataTypeName: string) { await this.clickRootFolderCaretButton(); - await expect(this.sectionSidebar.getByLabel(dataTypeName, {exact: true})).toBeVisible(); - await this.sectionSidebar.getByLabel(dataTypeName, {exact: true}).click(); + await this.click(this.sectionSidebar.getByLabel(dataTypeName, {exact: true})); } async clickMoveToButton() { - await expect(this.moveToBtn).toBeVisible(); - await this.moveToBtn.click(); + await this.click(this.moveToBtn); } async clickDuplicateToButton() { - await expect(this.duplicateToBtn).toBeVisible(); - await this.duplicateToBtn.click(); + await this.click(this.duplicateToBtn); } async waitForDataTypeToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async isDataTypeTreeItemVisible(name: string, isVisible: boolean = true) { - { - const hasShowChildren = await this.dataTypeTreeRoot.getAttribute('show-children') !== null; + const hasShowChildren = await this.dataTypeTreeRoot.getAttribute('show-children') !== null; - if (!hasShowChildren) { - await this.dataTypeTreeRoot.locator(this.caretBtn).first().click(); - } - - await this.isTreeItemVisible(name, isVisible); + if (!hasShowChildren) { + await this.click(this.dataTypeTreeRoot.locator(this.caretBtn).first()); } + + await this.isTreeItemVisible(name, isVisible); } async waitForDataTypeToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForDataTypeToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async clickNewDataTypeButton() { - await expect(this.newDataTypeBtn).toBeVisible(); - await this.newDataTypeBtn.click(); + await this.click(this.newDataTypeBtn); } async clickNewDataTypeFolderButton() { - await expect(this.newFolderBtn).toBeVisible(); - await this.newFolderBtn.click(); + await this.click(this.newFolderBtn); } async enterDataTypeName(name: string) { - await expect(this.dataTypeNameTxt).toBeVisible(); - await this.dataTypeNameTxt.click(); - await this.dataTypeNameTxt.clear(); - await this.dataTypeNameTxt.fill(name); + await this.click(this.dataTypeNameTxt); + await this.enterText(this.dataTypeNameTxt, name); } async clickCreateFolderButton() { - await expect(this.createFolderBtn).toBeVisible(); - await this.createDataTypeFolderBtn.click(); - await this.page.waitForTimeout(500); // Wait for the action to complete + await this.click(this.createDataTypeFolderBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickUpdateFolderButton() { - await expect(this.updateDataTypeFolderBtn).toBeVisible(); - await this.updateDataTypeFolderBtn.click(); + await this.click(this.updateDataTypeFolderBtn); } async deleteDataType(name: string) { @@ -422,31 +412,28 @@ export class DataTypeUiHelper extends UiBaseLocators { async moveDataTypeToFolder(folderName: string) { await this.clickMoveToActionMenuOption(); - await expect(this.sidebarModal.getByText(folderName, {exact: true})).toBeVisible(); - await this.sidebarModal.getByText(folderName, {exact: true}).click(); - await this.chooseModalBtn.click(); + await this.click(this.sidebarModal.getByText(folderName, {exact: true})); + await this.click(this.chooseModalBtn); } async duplicateDataTypeToFolder(folderName: string) { await this.clickDuplicateToActionMenuOption(); - await expect(this.sidebarModal.getByText(folderName, {exact: true})).toBeVisible(); - await this.sidebarModal.getByText(folderName, {exact: true}).click(); - await this.duplicateBtn.click(); + await this.click(this.sidebarModal.getByText(folderName, {exact: true})); + await this.click(this.duplicateBtn); } async addMediaStartNode(mediaName: string) { - await expect(this.mediaCardItems.filter({hasText: mediaName})).toBeVisible(); - await this.mediaCardItems.filter({hasText: mediaName}).click(); + await this.click(this.mediaCardItems.filter({hasText: mediaName})); await this.clickChooseModalButton(); } async addContentStartNode(contentName: string) { await this.clickTextButtonWithName(contentName); - await this.chooseModalBtn.click(); + await this.click(this.chooseModalBtn); } async clickSelectAPropertyEditorButton() { - await this.selectAPropertyEditorBtn.click(); + await this.click(this.selectAPropertyEditorBtn); } async selectAPropertyEditor(propertyName: string, filterKeyword?: string) { @@ -456,51 +443,48 @@ export class DataTypeUiHelper extends UiBaseLocators { // Approved Color async clickIncludeLabelsToggle() { - await this.includeLabelsToggle.click(); + await this.click(this.includeLabelsToggle); } async removeColorByValue(value: string) { - await this.page.locator('[value="' + value + '"] uui-button svg').click(); - await this.confirmToDeleteBtn.click(); + await this.click(this.page.locator(`[value="${value}"] uui-button svg`)); + await this.click(this.confirmToDeleteBtn); } async addColor(value: string) { - await this.addColorBtn.click(); - await this.colorValueTxt.clear(); - await this.colorValueTxt.fill(value); + await this.click(this.addColorBtn); + await this.enterText(this.colorValueTxt, value); } // Label async changeValueType(valueType: string) { - await this.page.getByLabel('Select a value type').selectOption({label: valueType}); + await this.selectByText(this.page.getByLabel('Select a value type'), valueType); } // Date Picker async clickOffsetTimeToggle() { - await this.offsetTimeToggle.click(); + await this.click(this.offsetTimeToggle); } async enterDateFormatValue(value: string) { - await this.dateFormatTxt.clear(); - await this.dateFormatTxt.fill(value); + await this.enterText(this.dateFormatTxt, value); } // List View async enterPageSizeValue(value: string) { - await this.pageSizeTxt.clear(); - await this.pageSizeTxt.fill(value); + await this.enterText(this.pageSizeTxt, value); } async chooseOrderDirection(isAscending: boolean) { if (isAscending) { - await this.ascendingRadioBtn.click(); + await this.click(this.ascendingRadioBtn); } else { - await this.descendingRadioBtn.click(); + await this.click(this.descendingRadioBtn); } } async addColumnDisplayed(contentType: string, contentName: string, propertyAlias: string) { - await this.chooseColumnsDisplayedBtn.click(); + await this.click(this.chooseColumnsDisplayedBtn); await this.clickTextButtonWithName(contentType); await this.clickTextButtonWithName(contentName); await this.clickChooseContainerButton(); @@ -508,263 +492,221 @@ export class DataTypeUiHelper extends UiBaseLocators { } async removeColumnDisplayed(propertyAlias: string) { - await this.columnsDisplayedItems.filter({has: this.page.getByText(propertyAlias, {exact: true})}).getByText('Remove').click(); + await this.click(this.columnsDisplayedItems.filter({has: this.page.getByText(propertyAlias, {exact: true})}).getByText('Remove')); } async addLayouts(layoutName: string) { - await expect(this.chooseLayoutsBtn).toBeVisible(); - await this.chooseLayoutsBtn.click(); - await expect(this.page.locator('[name="' + layoutName + '"]')).toBeVisible(); - await this.page.locator('[name="' + layoutName + '"]').click(); + await this.click(this.chooseLayoutsBtn); + await this.click(this.page.locator(`[name="${layoutName}"]`)); } async removeLayouts(layoutAlias: string) { - await this.layoutsItems.filter({has: this.page.getByText(layoutAlias, {exact: true})}).getByText('Remove').click(); + await this.click(this.layoutsItems.filter({has: this.page.getByText(layoutAlias, {exact: true})}).getByText('Remove')); } async chooseOrderByValue(value: string) { - await this.orderByDropDownBox.selectOption({label: value}); + await this.selectByText(this.orderByDropDownBox, value); } async enterWorkspaceViewName(name: string) { - await this.workspaceViewName.clear(); - await this.workspaceViewName.fill(name); + await this.enterText(this.workspaceViewName, name); } async clickShowContentWorkspaceViewFirstToggle() { - await this.showWorkspaceViewFirstToggle.click(); + await this.click(this.showWorkspaceViewFirstToggle); } async clickEditInInfiniteEditorToggle() { - await this.editInInfiniteEditorToggle.click(); + await this.click(this.editInInfiniteEditorToggle); } async clickBulkActionPermissionsToggleByValue(value: string) { - await this.page.locator("uui-toggle[label='" + value + "'] #toggle").click(); + await this.click(this.page.locator(`uui-toggle[label='${value}'] #toggle`)); } async clickSelectIconButton() { - await expect(this.selectIconBtn).toBeVisible(); // Force click is needed - await this.selectIconBtn.click({force: true}); + await this.click(this.selectIconBtn, {force: true}); } async chooseWorkspaceViewIconByValue(value: string) { - await this.page.locator('[label="' + value + '"] svg').click(); - await this.submitBtn.click(); + await this.click(this.page.locator(`[label="${value}"] svg`)); + await this.click(this.submitBtn); } // Image Cropper async enterCropValues(label: string, alias: string, width: string, height: string) { - await expect(this.labelTxt).toBeVisible(); - await this.labelTxt.clear(); - await this.labelTxt.fill(label); - await expect(this.aliasTxt).toBeVisible(); - await this.aliasTxt.clear(); - await this.aliasTxt.fill(alias); - await expect(this.widthTxt).toBeVisible(); - await this.widthTxt.clear(); - await this.widthTxt.fill(width); - await this.heightTxt.clear(); - await this.heightTxt.fill(height); + await this.enterText(this.labelTxt, label); + await this.enterText(this.aliasTxt, alias); + await this.enterText(this.widthTxt, width); + await this.enterText(this.heightTxt, height); } async clickCreateCropButton() { - await expect(this.createCropBtn).toBeVisible(); - await this.createCropBtn.click(); + await this.click(this.createCropBtn); } async clickEditCropButton() { - await expect(this.editCropBtn).toBeVisible(); - await this.editCropBtn.click(); + await this.click(this.editCropBtn); } async editCropByAlias(alias: string) { - await expect(this.page.locator('.crop').filter({has: this.page.getByText(alias)}).getByText('Edit')).toBeVisible(); - await this.page.locator('.crop').filter({has: this.page.getByText(alias)}).getByText('Edit').click(); + await this.click(this.page.locator('.crop').filter({has: this.page.getByText(alias)}).getByText('Edit')); } async removeCropByAlias(alias: string) { - await expect(this.page.locator('.crop').filter({has: this.page.getByText(alias)}).getByText('Remove')).toBeVisible(); - await this.page.locator('.crop').filter({has: this.page.getByText(alias)}).getByText('Remove').click(); + await this.click(this.page.locator('.crop').filter({has: this.page.getByText(alias)}).getByText('Remove')); } // Numeric async enterMinimumValue(value: string) { - await expect(this.minimumTxt).toBeVisible(); - await this.minimumTxt.clear(); - await this.minimumTxt.fill(value); + await this.enterText(this.minimumTxt, value); } async enterMaximumValue(value: string) { - await expect(this.maximumTxt).toBeVisible(); - await this.maximumTxt.clear(); - await this.maximumTxt.fill(value); + await this.enterText(this.maximumTxt, value); } async enterStepSizeValue(value: string) { - await expect(this.stepSizeTxt).toBeVisible(); - await this.stepSizeTxt.clear(); - await this.stepSizeTxt.fill(value); + await this.enterText(this.stepSizeTxt, value); } async clickAllowDecimalsToggle() { - await expect(this.allowDecimalsToggle).toBeVisible(); - await this.allowDecimalsToggle.click(); + await this.click(this.allowDecimalsToggle); } // Radiobox async removeOptionByName(name: string) { - await expect(this.page.locator("uui-button[label='Remove " + name + "'] svg")).toBeVisible(); - await this.page.locator("uui-button[label='Remove " + name + "'] svg").click(); - await this.confirmToDeleteBtn.click(); + await this.click(this.page.locator(`uui-button[label='Remove ${name}'] svg`)); + await this.click(this.confirmToDeleteBtn); } async enterOptionName(name: string) { - await expect(this.optionTxt.last()).toBeVisible(); - await this.optionTxt.last().clear(); - await this.optionTxt.last().fill(name); + await this.enterText(this.optionTxt.last(), name); } async clickAddOptionButton() { - await expect(this.addOptionBtn).toBeVisible(); - await this.addOptionBtn.click(); + await this.click(this.addOptionBtn); } // Textarea - Textstring async enterMaximumAllowedCharactersValue(value: string) { - await expect(this.maximumAllowedCharsTxt).toBeVisible(); - await this.maximumAllowedCharsTxt.clear(); - await this.maximumAllowedCharsTxt.fill(value); + await this.enterText(this.maximumAllowedCharsTxt, value); } async enterNumberOfRowsValue(value: string) { - await expect(this.numberOfRowsTxt).toBeVisible(); - await this.numberOfRowsTxt.clear(); - await this.numberOfRowsTxt.fill(value); + await this.enterText(this.numberOfRowsTxt, value); } async enterMaxHeightValue(value: string) { - await expect(this.maxHeightTxt).toBeVisible(); - await this.maxHeightTxt.clear(); - await this.maxHeightTxt.fill(value); + await this.enterText(this.maxHeightTxt, value); } async enterMinHeightValue(value: string) { - await this.minHeightTxt.clear(); - await this.minHeightTxt.fill(value); + await this.enterText(this.minHeightTxt, value); } // Upload async enterAcceptedFileExtensions(value: string) { - await this.acceptedFileExtensionsTxt.last().clear(); - await this.acceptedFileExtensionsTxt.last().fill(value); + await this.enterText(this.acceptedFileExtensionsTxt.last(), value); } async removeAcceptedFileExtensionsByValue(value: string) { - await this.page.locator("uui-button[label='Remove " + value + "'] svg").click(); - await this.confirmToDeleteBtn.click(); + await this.click(this.page.locator(`uui-button[label='Remove ${value}'] svg`)); + await this.click(this.confirmToDeleteBtn); } async clickAddAcceptedFileExtensionsButton() { - await this.addAcceptedFileExtensionsBtn.click(); + await this.click(this.addAcceptedFileExtensionsBtn); } // Multi URL Picker async enterMinimumNumberOfItemsValue(value: string) { - await this.minimumNumberOfItemsTxt.clear(); - await this.minimumNumberOfItemsTxt.fill(value); + await this.enterText(this.minimumNumberOfItemsTxt, value); } async enterMaximumNumberOfItemsValue(value: string) { - await this.maximumNumberOfItemsTxt.clear(); - await this.maximumNumberOfItemsTxt.fill(value); + await this.enterText(this.maximumNumberOfItemsTxt, value); } async clickIgnoreUserStartNodesToggle() { - await this.ignoreUserStartNodesToggle.click(); + await this.click(this.ignoreUserStartNodesToggle); } async chooseOverlaySizeByValue(value: string) { - await this.overlaySizeDropDownBox.selectOption({value: value}); + await this.selectByValue(this.overlaySizeDropDownBox, value); } async clickHideAnchorQueryStringInputToggle() { - await this.hideAnchorQueryStringInputToggle.click(); + await this.click(this.hideAnchorQueryStringInputToggle); } // Media Picker async clickPickMultipleItemsToggle() { - await this.pickMultipleItemsToggle.click(); + await this.click(this.pickMultipleItemsToggle); } async clickEnableFocalPointToggle() { - await expect(this.enableFocalPointToggle).toBeVisible(); - await this.enableFocalPointToggle.click(); + await this.click(this.enableFocalPointToggle); } async enterAmountValue(lowValue: string, highValue: string) { - await this.amountLowValueTxt.clear(); - await this.amountLowValueTxt.fill(lowValue); - await this.amountHighValueTxt.clear(); - await this.amountHighValueTxt.fill(highValue); + await this.enterText(this.amountLowValueTxt, lowValue); + await this.enterText(this.amountHighValueTxt, highValue); } async addAcceptedType(mediaTypeName: string) { - await this.chooseAcceptedTypesBtn.click(); + await this.click(this.chooseAcceptedTypesBtn); await this.clickTextButtonWithName(mediaTypeName); - await this.chooseModalBtn.click(); + await this.click(this.chooseModalBtn); } async removeAcceptedType(mediaTypeName: string) { - await this.page.locator('uui-ref-node-document-type[name="' + mediaTypeName + '"]').getByLabel('Remove').click(); - await this.confirmToRemoveBtn.click(); + await this.click(this.page.locator(`uui-ref-node-document-type[name="${mediaTypeName}"]`).getByLabel('Remove')); + await this.click(this.confirmToRemoveBtn); } async removeMediaStartNode(mediaName: string) { - await this.page.locator('uui-card-media[name="' + mediaName + '"]').locator('[label="Remove"]').click(); - await this.confirmToRemoveBtn.click(); + await this.click(this.page.locator(`uui-card-media[name="${mediaName}"]`).locator('[label="Remove"]')); + await this.click(this.confirmToRemoveBtn); } async clickChooseStartNodeButton() { - await this.chooseStartNodeBtn.click(); + await this.click(this.chooseStartNodeBtn); } // Richtext Editor async clickToolbarOptionByValue(values) { for (var index in values) { - await this.toolbarCheckboxes.filter({has: this.page.getByLabel(values[index])}).locator('#ticker svg').click(); + await this.click(this.toolbarCheckboxes.filter({has: this.page.getByLabel(values[index])}).locator('#ticker svg')); } } async addStylesheet(stylesheetName: string) { - await this.addStylesheetBtn.click(); - await this.page.getByLabel(stylesheetName).click(); - await this.chooseModalBtn.click(); + await this.click(this.addStylesheetBtn); + await this.click(this.page.getByLabel(stylesheetName)); + await this.click(this.chooseModalBtn); } async enterDimensionsValue(width: string, height: string) { - await this.dimensionsWidthTxt.clear(); - await this.dimensionsWidthTxt.fill(width); - await this.dimensionsHeightTxt.clear(); - await this.dimensionsHeightTxt.fill(height); + await this.enterText(this.dimensionsWidthTxt, width); + await this.enterText(this.dimensionsHeightTxt, height); } async enterMaximumSizeForImages(value: string) { - await this.maxImageSizeTxt.clear(); - await this.maxImageSizeTxt.fill(value); + await this.enterText(this.maxImageSizeTxt, value); } async clickHideLabelToggle() { - await this.hideLabelToggle.click(); + await this.click(this.hideLabelToggle); } async clickInlineRadioButton() { - await this.inlineRadioBtn.click(); + await this.click(this.inlineRadioBtn); } async clickChooseWithPlusButton() { - await this.chooseWithPlusBtn.click(); + await this.click(this.chooseWithPlusBtn); } async addImageUploadFolder(mediaFolderName: string) { @@ -774,8 +716,7 @@ export class DataTypeUiHelper extends UiBaseLocators { } async clickAddWithPlusButton() { - await expect(this.addWithPlusBtn).toBeVisible(); - await this.addWithPlusBtn.click(); + await this.click(this.addWithPlusBtn); } async addAvailableBlocks(blockName: string) { @@ -787,86 +728,67 @@ export class DataTypeUiHelper extends UiBaseLocators { // Tags async enterDefineTagGroupValue(value: string) { - await expect(this.defineTagGroupTxt).toBeVisible(); - await this.defineTagGroupTxt.clear(); - await this.defineTagGroupTxt.fill(value); + await this.enterText(this.defineTagGroupTxt, value); } async selectStorageTypeOption(option: string) { - await expect(this.storageTypeDropDownBox).toBeVisible(); - await this.storageTypeDropDownBox.selectOption({label: option}); + await this.selectByText(this.storageTypeDropDownBox, option); } // Content Picker async clickShowOpenButtonToggle() { - await expect(this.showOpenButtonToggle).toBeVisible(); - await this.showOpenButtonToggle.click(); + await this.click(this.showOpenButtonToggle); } async removeContentStartNode(contentName: string) { - const startNodeLocator = this.entityItem.filter({has: this.page.locator('[name="' + contentName + '"]')}); - await startNodeLocator.hover(); - await startNodeLocator.getByLabel('Remove').click(); + const startNodeLocator = this.entityItem.filter({has: this.page.locator(`[name="${contentName}"]`)}); + await this.hoverAndClick(startNodeLocator, startNodeLocator.getByLabel('Remove')); await this.clickConfirmRemoveButton(); } // Dropdown async clickEnableMultipleChoiceToggle() { - await expect(this.enableMultipleChoiceToggle).toBeVisible(); - await this.enableMultipleChoiceToggle.click(); + await this.click(this.enableMultipleChoiceToggle); } async clickAddOptionsButton() { - await expect(this.addOptionsBtn).toBeVisible(); - await this.addOptionsBtn.click(); + await this.click(this.addOptionsBtn); } // True/false async clickPresetValueToggle() { - await expect(this.presetValueToggle).toBeVisible(); - await this.presetValueToggle.click(); + await this.click(this.presetValueToggle); } async clickShowToggleLabelsToggle() { - await expect(this.showToggleLabelsToggle).toBeVisible(); - await this.showToggleLabelsToggle.click(); + await this.click(this.showToggleLabelsToggle); } async enterLabelOnValue(value: string) { - await expect(this.labelOnTxt).toBeVisible(); - await this.labelOnTxt.clear(); - await this.labelOnTxt.fill(value); + await this.enterText(this.labelOnTxt, value); } async enterLabelOffValue(value: string) { - await expect(this.labelOffTxt).toBeVisible(); - await this.labelOffTxt.clear(); - await this.labelOffTxt.fill(value); + await this.enterText(this.labelOffTxt, value); } // Block List Editor async clickAddBlockButton(index: number = 0) { - await expect(this.addBlockBtn.nth(index)).toBeVisible(); - await this.addBlockBtn.nth(index).click(); + await this.click(this.addBlockBtn.nth(index)); } async clickRemoveBlockWithName(name: string) { const blockWithNameLocator = this.page.locator('umb-block-type-card', {hasText: name}); - await expect(blockWithNameLocator).toBeVisible(); - // The force click is necessary. - await blockWithNameLocator.getByLabel('Remove block').click({force: true}); + // The force click is necessary. + await this.click(blockWithNameLocator.getByLabel('Remove block'), {force: true}); } async enterMinAmount(value: string) { - await expect(this.minAmountTxt).toBeVisible() - await this.minAmountTxt.clear(); - await this.minAmountTxt.fill(value); + await this.enterText(this.minAmountTxt, value); } async enterMaxAmount(value: string) { - await expect(this.maxAmountTxt).toBeVisible() - await this.maxAmountTxt.clear(); - await this.maxAmountTxt.fill(value); + await this.enterText(this.maxAmountTxt, value); } async doesAmountContainErrorMessageWithText(errorMessage: string) { @@ -874,29 +796,23 @@ export class DataTypeUiHelper extends UiBaseLocators { } async clickSingleBlockMode() { - await expect(this.singleBlockModeBtn).toBeVisible() - await this.singleBlockModeBtn.click(); + await this.click(this.singleBlockModeBtn); } async clickLiveEditingMode() { - await expect(this.liveEditingModeBtn).toBeVisible(); - await this.liveEditingModeBtn.click(); + await this.click(this.liveEditingModeBtn); } async clickInlineEditingMode() { - await expect(this.inlineEditingModeBtn).toBeVisible(); - await this.inlineEditingModeBtn.click(); + await this.click(this.inlineEditingModeBtn); } async enterPropertyEditorWidth(width: string) { - await expect(this.propertyEditorWidthTxt).toBeVisible(); - await this.propertyEditorWidthTxt.clear(); - await this.propertyEditorWidthTxt.fill(width); + await this.enterText(this.propertyEditorWidthTxt, width); } async goToBlockWithName(name: string) { - await expect(this.page.getByRole('link', {name: name})).toBeVisible(); - await this.page.getByRole('link', {name: name}).click(); + await this.click(this.page.getByRole('link', {name: name})); } async enterBlockLabelText(label: string) { @@ -905,65 +821,48 @@ export class DataTypeUiHelper extends UiBaseLocators { } async removeBlockLabelText() { - await expect(this.labelTextTxt).toBeVisible(); + await this.waitForVisible(this.labelTextTxt); await this.labelTextTxt.clear(); } async clickAllowInRootForBlock() { - await expect(this.allowBlockAtRootToggle).toBeVisible(); - await this.allowBlockAtRootToggle.click(); + await this.click(this.allowBlockAtRootToggle); } async clickAllowInAreasForBlock() { - await expect(this.allowInAreasToggle).toBeVisible(); - await this.allowInAreasToggle.click(); + await this.click(this.allowInAreasToggle); } async updateBlockOverlaySize(size: string) { - await expect(this.overlaySizeOption).toBeVisible(); - await this.overlaySizeOption.selectOption(size); + await this.selectByValue(this.overlaySizeOption, size); } async addBlockContentModel(elementName: string) { - await expect(this.chooseContentModelBtn).toBeVisible(); - await this.chooseContentModelBtn.click(); + await this.click(this.chooseContentModelBtn); await this.clickButtonWithName(elementName); await this.clickChooseButton(); } async addBlockSettingsModel(elementName: string) { - await expect(this.chooseSettingsModelBtn).toBeVisible(); - await this.chooseSettingsModelBtn.click(); + await this.click(this.chooseSettingsModelBtn, {timeout: ConstantHelper.timeout.long}); await this.clickModalMenuItemWithName(elementName); await this.clickChooseModalButton(); } async removeBlockContentModel() { - await expect(this.contentModelNode).toBeVisible(); - await this.contentModelNode.hover(); - await expect(this.removeExactContentModelNodeBtn).toBeVisible(); - await this.removeExactContentModelNodeBtn.click(); + await this.hoverAndClick(this.contentModelNode, this.removeExactContentModelNodeBtn); } async removeBlockSettingsModel() { - await expect(this.settingsModelNode).toBeVisible(); - await this.settingsModelNode.hover(); - await expect(this.removeExactSettingsModelNodeBtn).toBeVisible(); - await this.removeExactSettingsModelNodeBtn.click(); + await this.hoverAndClick(this.settingsModelNode, this.removeExactSettingsModelNodeBtn); } async openBlockContentModel() { - await expect(this.contentModelNode).toBeVisible(); - await this.contentModelNode.hover(); - await expect(this.openBtn).toBeVisible(); - await this.openBtn.click(); + await this.hoverAndClick(this.contentModelNode, this.openBtn); } async openBlockSettingsModel() { - await expect(this.settingsModelNode).toBeVisible(); - await this.settingsModelNode.hover(); - await expect(this.openBtn).toBeVisible(); - await this.openBtn.click(); + await this.hoverAndClick(this.settingsModelNode, this.openBtn); } async isElementWorkspaceOpenInBlock(elementTypeName: string) { @@ -971,40 +870,31 @@ export class DataTypeUiHelper extends UiBaseLocators { } async selectBlockBackgroundColor(color: string) { - await expect(this.backgroundColorBtn).toBeVisible(); - await this.backgroundColorBtn.click(); - await this.backgroundColorTxt.clear(); - await this.backgroundColorTxt.fill(color); + await this.click(this.backgroundColorBtn); + await this.enterText(this.backgroundColorTxt, color); } async selectBlockIconColor(color: string) { - await expect(this.iconColorBtn).toBeVisible(); - await this.iconColorBtn.click(); - await this.iconColorTxt.clear(); - await this.iconColorTxt.fill(color); + await this.click(this.iconColorBtn); + await this.enterText(this.iconColorTxt, color); } async clickExpandChildItemsForMediaButton() { - await expect(this.expandChildItemsForMediaBtn).toBeVisible(); - await this.expandChildItemsForMediaBtn.click(); + await this.click(this.expandChildItemsForMediaBtn); } async clickRemoveCustomStylesheetWithName(name: string) { - await expect(this.customStylesheetLabel.locator('[name="' + name + '"]')).toBeVisible(); - await this.customStylesheetLabel.locator('[name="' + name + '"]').click(); - await expect(this.stylesheetRemoveBtn).toBeVisible(); - await this.stylesheetRemoveBtn.click(); + await this.click(this.customStylesheetLabel.locator(`[name="${name}"]`)); + await this.click(this.stylesheetRemoveBtn); await this.clickConfirmRemoveButton(); } async clickBlockGridHideContentEditorButton() { - await expect(this.hideContentEditorBlockGridBtn).toBeVisible(); - await this.hideContentEditorBlockGridBtn.click(); + await this.click(this.hideContentEditorBlockGridBtn); } async chooseBlockCustomStylesheetWithName(name: string) { - await expect(this.chooseCustomStylesheetBtn).toBeVisible(); - await this.chooseCustomStylesheetBtn.click(); + await this.click(this.chooseCustomStylesheetBtn); await this.openCaretButtonForName('wwwroot'); await this.openCaretButtonForName('css'); await this.clickLabelWithName(name, true); @@ -1013,39 +903,33 @@ export class DataTypeUiHelper extends UiBaseLocators { async chooseBlockThumbnailWithPath(mediaPath: string) { const mediaItems = mediaPath.split('/media/')[1].split('/'); - await expect(this.chooseThumbnailAlias).toBeVisible(); - await this.chooseThumbnailAlias.click(); + await this.click(this.chooseThumbnailAlias); await this.openCaretButtonForName('wwwroot', true); await this.clickExpandChildItemsForMediaButton(); for (let i = 0; i < mediaItems.length; i++) { if (i === mediaItems.length - 1) { await this.clickLabelWithName(mediaItems[i], true); } else { - await this.sidebarModal.locator('uui-menu-item[label="' + mediaItems[i] + '"] #caret-button').click(); + await this.click(this.sidebarModal.locator(`uui-menu-item[label="${mediaItems[i]}"] #caret-button`)); } } await this.clickChooseModalButton(); } async clickBlockListHideContentEditorButton() { - await expect(this.hideContentEditorBlockListBtn).toBeVisible(); - await this.hideContentEditorBlockListBtn.click(); + await this.click(this.hideContentEditorBlockListBtn); } async enterEditorWidth(value: string) { - await expect(this.editorWidthTxt).toBeVisible(); - await this.editorWidthTxt.clear(); - await this.editorWidthTxt.fill(value); + await this.enterText(this.editorWidthTxt, value); } async enterCreateButtonLabel(value: string) { - await expect(this.createButtonLabelTxt).toBeVisible(); - await this.createButtonLabelTxt.clear(); - await this.createButtonLabelTxt.fill(value); + await this.enterText(this.createButtonLabelTxt, value); } async enterGridColumns(value: number) { - await expect(this.gridColumnsTxt).toBeVisible(); + await this.waitForVisible(this.gridColumnsTxt); await this.gridColumnsTxt.clear(); if (value === undefined) { return; @@ -1054,24 +938,21 @@ export class DataTypeUiHelper extends UiBaseLocators { } async clickShowResizeOptions() { - await expect(this.showResizeOptionsBtn).toBeVisible(); - await this.showResizeOptionsBtn.click(); + await this.click(this.showResizeOptionsBtn); } async clickAvailableColumnSpans(columnSpans: number[]) { for (let index in columnSpans) { - await expect(this.columnSpanOptions.getByLabel(columnSpans[index].toString(), {exact: true})).toBeVisible(); - await this.columnSpanOptions.getByLabel(columnSpans[index].toString(), {exact: true}).click(); + await this.click(this.columnSpanOptions.getByLabel(columnSpans[index].toString(), {exact: true})); } } async goToBlockAreasTab() { - await expect(this.areasTabBtn).toBeVisible(); - await this.areasTabBtn.click(); + await this.click(this.areasTabBtn); } async enterMinRowSpan(value: number) { - await expect(this.availableRowSpansLowValueTxt).toBeVisible(); + await this.waitForVisible(this.availableRowSpansLowValueTxt); await this.availableRowSpansLowValueTxt.clear(); if (value === undefined) { return; @@ -1080,7 +961,7 @@ export class DataTypeUiHelper extends UiBaseLocators { } async enterMaxRowSpan(value: number) { - await expect(this.availableRowSpansHighValueTxt).toBeVisible(); + await this.waitForVisible(this.availableRowSpansHighValueTxt); await this.availableRowSpansHighValueTxt.clear(); if (value === undefined) { return; @@ -1089,7 +970,7 @@ export class DataTypeUiHelper extends UiBaseLocators { } async enterGridColumnsForArea(value: number) { - await expect(this.areaGridColumnsTxt).toBeVisible(); + await this.waitForVisible(this.areaGridColumnsTxt); await this.areaGridColumnsTxt.clear(); if (value === undefined) { return; @@ -1098,37 +979,33 @@ export class DataTypeUiHelper extends UiBaseLocators { } async addAreaButton() { - await expect(this.addAreaBtn).toBeVisible(); - await this.addAreaBtn.click(); + await this.click(this.addAreaBtn); } async goToAreaByAlias(alias: string) { const editAreaWithAliasLocator = this.blockAreaConfig.filter({hasText: alias}).getByLabel('edit'); - await expect(editAreaWithAliasLocator).toBeVisible(); - await editAreaWithAliasLocator.click({force: true}); + // Force click is needed + await this.click(editAreaWithAliasLocator, {force: true}); } async clickRemoveAreaByAlias(alias: string) { const removeAreaWithAliasLocator = this.blockAreaConfig.filter({hasText: alias}).getByLabel('delete'); - await expect(removeAreaWithAliasLocator).toBeVisible(); - await removeAreaWithAliasLocator.click({force: true}); + // Force click is needed + await this.click(removeAreaWithAliasLocator, {force: true}); await this.clickConfirmToDeleteButton(); } async enterAreaAlias(alias: string) { - await expect(this.aliasAliasTxt).toBeVisible(); - await this.aliasAliasTxt.clear(); - await this.aliasAliasTxt.fill(alias); + await this.enterText(this.aliasAliasTxt, alias); } async clickAreaSubmitButton() { - await expect(this.blockGridAreaWorkspaceSubmitBtn).toBeVisible(); - await this.blockGridAreaWorkspaceSubmitBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.blockGridAreaWorkspaceSubmitBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async enterCreateButtonLabelInArea(value: string) { - await expect(this.createLabelTxt.nth(1)).toBeVisible(); + await this.waitForVisible(this.createLabelTxt.nth(1)); await this.createLabelTxt.nth(1).clear(); if (value === undefined) { return; @@ -1137,7 +1014,7 @@ export class DataTypeUiHelper extends UiBaseLocators { } async enterMinAllowedInArea(value: number) { - await expect(this.minAllowedTxt).toBeVisible(); + await this.waitForVisible(this.minAllowedTxt); await this.minAllowedTxt.clear(); if (value === undefined) { return; @@ -1146,7 +1023,7 @@ export class DataTypeUiHelper extends UiBaseLocators { } async enterMaxAllowedInArea(value: number) { - await expect(this.maxAllowedTxt).toBeVisible(); + await this.waitForVisible(this.maxAllowedTxt); await this.maxAllowedTxt.clear(); if (value === undefined) { return; @@ -1155,13 +1032,11 @@ export class DataTypeUiHelper extends UiBaseLocators { } async clickAddSpecifiedAllowanceButton() { - await expect(this.addSpecifiedAllowanceBtn).toBeVisible(); - await this.addSpecifiedAllowanceBtn.click(); + await this.click(this.addSpecifiedAllowanceBtn); } async goToBlockAdvancedTab() { - await expect(this.advancedTabBtn).toBeVisible(); - await this.advancedTabBtn.click(); + await this.click(this.advancedTabBtn); } async getLinkWithName(name: string) { @@ -1176,65 +1051,56 @@ export class DataTypeUiHelper extends UiBaseLocators { async clickRemoveStylesheetButton(stylesheetName: string) { const removeButton = this.entityItem.filter({hasText: stylesheetName}).getByLabel('Remove'); - await expect(removeButton).toBeVisible(); - await removeButton.click(); + await this.click(removeButton); } // TipTap async deleteToolbarGroup(groupIndex: number, rowIndex: number = 0) { const groupButton = this.tiptapToolbarConfiguration.locator('.row').nth(rowIndex).locator('.group').nth(groupIndex); - await expect(groupButton).toBeVisible(); - await groupButton.hover(); + await this.hover(groupButton); const actionsInGroup = groupButton.locator('.items').locator('uui-button'); const actionsCount = await actionsInGroup.count(); for (let i = 0; i < actionsCount; i++) { - await actionsInGroup.first().click(); + await this.click(actionsInGroup.first()); } - await groupButton.locator('[label="Remove group"]').click(); + await this.click(groupButton.locator('[label="Remove group"]')); } async deleteToolbarRow(rowIndex: number) { const rowButton = this.tiptapToolbarConfiguration.locator('.row').nth(rowIndex); - await expect(rowButton).toBeVisible(); - await rowButton.hover(); - await rowButton.locator('[label="Remove row"]').click(); + await this.hoverAndClick(rowButton, rowButton.locator('[label="Remove row"]')); } async clickAddRowToolbarButton() { - await expect(this.addRowToolbarBtn).toBeVisible(); - await this.addRowToolbarBtn.click(); + await this.click(this.addRowToolbarBtn); } async clickAddGroupToolbarButton() { - await expect(this.addGroupToolbarBtn).toBeVisible(); - await this.addGroupToolbarBtn.click(); + await this.click(this.addGroupToolbarBtn); } async clickExtensionItemWithName(name: string) { - await expect(this.tiptapExtensionsConfiguration.locator('uui-checkbox[label="' + name + '"]')).toBeVisible(); - await this.tiptapExtensionsConfiguration.locator('uui-checkbox[label="' + name + '"]').click(); + await this.click(this.tiptapExtensionsConfiguration.locator(`uui-checkbox[label="${name}"]`)); } async doesPropertyEditorHaveUiAlias(uiAlias: string) { - await expect(this.propertyEditor).toHaveAttribute('alias', uiAlias); + await this.hasAttribute(this.propertyEditor, 'alias', uiAlias); } async doesPropertyEditorHaveName(name: string) { - await expect(this.propertyEditor).toHaveAttribute('name', name); + await this.hasAttribute(this.propertyEditor, 'name', name); } async doesPropertyEditorHaveAlias(alias: string) { - await expect(this.propertyEditor).toHaveAttribute('property-editor-schema-alias', alias); + await this.hasAttribute(this.propertyEditor, 'property-editor-schema-alias', alias); } async clickDataTypeButton() { - await expect(this.dataTypeBtn).toBeVisible(); - await this.dataTypeBtn.click(); + await this.click(this.dataTypeBtn); } async clickDataTypesMenu() { - await expect(this.dataTypesMenu).toBeVisible(); - await this.dataTypesMenu.click(); + await this.click(this.dataTypesMenu); } async doesSettingHaveValue(settings) { @@ -1247,49 +1113,44 @@ export class DataTypeUiHelper extends UiBaseLocators { } async doesSettingItemsHaveCount(settings) { - await expect(this.propertyEditorConfigItems).toHaveCount(Object.keys(settings).length); + await this.hasCount(this.propertyEditorConfigItems, Object.keys(settings).length); } async doesSettingsContainText(text: string) { - await expect(this.propertyEditorConfig).toContainText(text); + await this.containsText(this.propertyEditorConfig, text); } async clickStatusbarItemInToolboxWithName(name: string) { const statusbarItemLocator = this.tiptapStatusbarConfiguration.locator('#toolbox uui-button').filter({hasText: name}); - await expect(statusbarItemLocator).toBeVisible(); - await statusbarItemLocator.click(); + await this.click(statusbarItemLocator); } async clickStatusbarItemWithName(name: string) { const statusbarItemLocator = this.tiptapStatusbarConfiguration.locator('#statusbar uui-button').filter({hasText: name}); - await expect(statusbarItemLocator).toBeVisible(); - await statusbarItemLocator.click(); + await this.click(statusbarItemLocator); } async isExtensionItemChecked(itemName: string, isChecked: boolean = true) { - await expect(this.tiptapExtensionsConfiguration.locator('uui-checkbox[label="' + itemName + '"] input')).toBeChecked({checked: isChecked}); + await expect(this.tiptapExtensionsConfiguration.locator(`uui-checkbox[label="${itemName}"] input`)).toBeChecked({checked: isChecked}); } async doesBlockHaveThumbnailImage(thumbnailImageUrl: string) { - await expect(this.blockThumbnailImage).toHaveAttribute('src', thumbnailImageUrl); + await this.hasAttribute(this.blockThumbnailImage, 'src', thumbnailImageUrl); } async addTimeZones(timeZones: string[]) { for (let i = 0; i < timeZones.length; i++) { - expect(this.timeZoneDropDown).toBeVisible(); - await this.timeZoneDropDown.click(); - await this.timeZoneDropDown.getByText(timeZones[i]).click(); - await this.addTimeZoneBtn.click(); + await this.click(this.timeZoneDropDown); + await this.click(this.timeZoneDropDown.getByText(timeZones[i])); + await this.click(this.addTimeZoneBtn); } } - - async clickChooseDataSourceButton(){ - await expect(this.dataSourceChooseBtn).toBeVisible(); - await this.dataSourceChooseBtn.click(); + + async clickChooseDataSourceButton() { + await this.click(this.dataSourceChooseBtn); } async clickChooseThumbnailButton() { - await expect(this.chooseThumbnailAlias).toBeVisible(); - await this.chooseThumbnailAlias.click(); + await this.click(this.chooseThumbnailAlias); } } \ No newline at end of file diff --git a/lib/helpers/DictionaryUiHelper.ts b/lib/helpers/DictionaryUiHelper.ts index 1ba597e1..6e8cf67b 100644 --- a/lib/helpers/DictionaryUiHelper.ts +++ b/lib/helpers/DictionaryUiHelper.ts @@ -36,14 +36,11 @@ export class DictionaryUiHelper extends UiBaseLocators { } async clickCreateDictionaryItemButton() { - await expect(this.createDictionaryItemBtn).toBeVisible(); - await this.createDictionaryItemBtn.click(); + await this.click(this.createDictionaryItemBtn); } async enterDictionaryName(name: string) { - await expect(this.dictionaryNameTxt).toBeVisible(); - await this.dictionaryNameTxt.clear(); - await this.dictionaryNameTxt.fill(name); + await this.enterText(this.dictionaryNameTxt, name); } async clickActionsMenuForDictionary(name: string) { @@ -51,38 +48,37 @@ export class DictionaryUiHelper extends UiBaseLocators { } async enterSearchKeywordAndPressEnter(keyword: string) { - await this.searchTxt.clear(); - await this.searchTxt.fill(keyword); - await this.page.keyboard.press('Enter'); + await this.enterText(this.searchTxt, keyword); + await this.pressKey(this.searchTxt, 'Enter'); } async clickExportButton() { - await this.exportBtn.click(); + await this.click(this.exportBtn); } async clickImportButton() { - await this.importBtn.click(); + await this.click(this.importBtn); } async waitForDictionaryToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForDictionaryToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForDictionaryToBeImported() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async deleteDictionary() { await this.clickDeleteActionMenuOption(); - await this.confirmToDeleteBtn.click(); + await this.click(this.confirmToDeleteBtn); } async doesDictionaryListHaveText(text: string) { - await expect(this.dictionaryList).toBeVisible(); + await this.waitForVisible(this.dictionaryList); const allRows = await this.dictionaryListRows.all(); for (let currentRow of allRows) { const currentText = await currentRow.innerText(); @@ -96,23 +92,22 @@ export class DictionaryUiHelper extends UiBaseLocators { // This function will export dictionary and return the file name async exportDictionary(includesDescendants: boolean) { if (includesDescendants) { - await this.includeDescendantsCheckbox.click(); + await this.click(this.includeDescendantsCheckbox); } const [downloadPromise] = await Promise.all([ this.page.waitForEvent('download'), - await this.exportModalBtn.click() + await this.click(this.exportModalBtn) ]); return downloadPromise.suggestedFilename(); } async importDictionary(filePath: string) { await this.importFileTxt.setInputFiles(filePath); - await expect(this.importModalBtn).toBeVisible(); - await this.importModalBtn.click(); + await this.click(this.importModalBtn); } async isSearchResultMessageDisplayEmpty(message: string) { - return await expect(this.emptySearchResultMessage).toHaveText(message); + await this.hasText(this.emptySearchResultMessage, message); } async isDictionaryTreeItemVisible(dictionaryName: string, isVisible: boolean = true) { @@ -120,6 +115,6 @@ export class DictionaryUiHelper extends UiBaseLocators { } async doesDictionaryCollectionContainText(text: string) { - return await expect(this.dictionaryCollection).toContainText(text); + await this.containsText(this.dictionaryCollection, text); } } \ No newline at end of file diff --git a/lib/helpers/DocumentBlueprintUiHelper.ts b/lib/helpers/DocumentBlueprintUiHelper.ts index 6822b374..81efa4bd 100644 --- a/lib/helpers/DocumentBlueprintUiHelper.ts +++ b/lib/helpers/DocumentBlueprintUiHelper.ts @@ -27,11 +27,11 @@ export class DocumentBlueprintUiHelper extends UiBaseLocators{ } async waitForDocumentBlueprintToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForDocumentBlueprintToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async reloadDocumentBlueprintsTree() { @@ -41,7 +41,7 @@ export class DocumentBlueprintUiHelper extends UiBaseLocators{ async goToDocumentBlueprint(blueprintName: string) { await this.goToSection(ConstantHelper.sections.settings); await this.reloadDocumentBlueprintsTree(); - await this.page.getByLabel(blueprintName, {exact: true}).click(); + await this.click(this.page.getByLabel(blueprintName, {exact: true})); } async isDocumentBlueprintRootTreeItemVisible(blueprintName: string, isVisible: boolean = true, toReload: boolean = true){ @@ -52,19 +52,18 @@ export class DocumentBlueprintUiHelper extends UiBaseLocators{ } async clickCreateDocumentBlueprintButton() { - await this.createDocumentBlueprintBtn.click(); + await this.click(this.createDocumentBlueprintBtn); } - + async clickCreateNewDocumentBlueprintButton() { - await this.createNewDocumentBlueprintBtn.click(); + await this.click(this.createNewDocumentBlueprintBtn); } async enterDocumentBlueprintName(blueprintName: string) { - await expect(this.documentBlueprintNameTxt).toBeVisible(); - await this.documentBlueprintNameTxt.fill(blueprintName); + await this.enterText(this.documentBlueprintNameTxt, blueprintName); } async clickDeleteMenuButton() { - await this.deleteMenu.click(); + await this.click(this.deleteMenu); } } \ No newline at end of file diff --git a/lib/helpers/DocumentTypeUiHelper.ts b/lib/helpers/DocumentTypeUiHelper.ts index a5d1ebe8..44b51c9f 100644 --- a/lib/helpers/DocumentTypeUiHelper.ts +++ b/lib/helpers/DocumentTypeUiHelper.ts @@ -1,4 +1,5 @@ -import {UiBaseLocators} from "./UiBaseLocators"; +import {ConstantHelper} from "./ConstantHelper"; +import {UiBaseLocators} from "./UiBaseLocators"; import {expect, Locator, Page} from "@playwright/test"; export class DocumentTypeUiHelper extends UiBaseLocators { @@ -50,38 +51,31 @@ export class DocumentTypeUiHelper extends UiBaseLocators { } async clickNewDocumentTypeButton() { - await expect(this.newDocumentTypeBtn).toBeVisible(); - await this.newDocumentTypeBtn.click(); + await this.click(this.newDocumentTypeBtn); } async clickSharedAcrossCulturesToggle() { - await expect(this.sharedAcrossCulturesToggle).toBeVisible(); - await this.sharedAcrossCulturesToggle.click(); + await this.click(this.sharedAcrossCulturesToggle); } async clickDocumentTypeSettingsTab() { - await expect(this.documentTypeSettingsTabBtn).toBeVisible(); - await this.documentTypeSettingsTabBtn.click(); + await this.click(this.documentTypeSettingsTabBtn); } async clickDocumentTypeTemplatesTab() { - await expect(this.documentTypeTemplatesTabBtn).toBeVisible(); - await this.documentTypeTemplatesTabBtn.click(); + await this.click(this.documentTypeTemplatesTabBtn); } async clickVaryBySegmentsButton() { - await expect(this.varyBySegmentsBtn).toBeVisible(); - await this.varyBySegmentsBtn.click(); + await this.click(this.varyBySegmentsBtn); } async clickVaryByCultureButton() { - await expect(this.varyByCultureBtn).toBeVisible(); - await this.varyByCultureBtn.click(); + await this.click(this.varyByCultureBtn); } async clickPreventCleanupButton() { - await expect(this.preventCleanupBtn).toBeVisible(); - await this.preventCleanupBtn.click(); + await this.click(this.preventCleanupBtn); } async goToDocumentType(documentTypeName: string) { @@ -90,54 +84,48 @@ export class DocumentTypeUiHelper extends UiBaseLocators { } async waitForDocumentTypeToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); + // Extra wait as document type creation seems to take a bit longer sometimes + await this.waitForTimeout(ConstantHelper.wait.short); } async waitForDocumentTypeToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForDocumentTypeToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async enterDocumentTypeName(documentTypeName: string) { - await expect(this.enterAName).toBeVisible(); - await this.enterAName.fill(documentTypeName); - await expect(this.enterAName).toHaveValue(documentTypeName); + await this.enterText(this.enterAName, documentTypeName, {verify: true}); } async clickCreateDocumentTypeButton() { - await expect(this.createDocumentTypeBtn).toBeVisible(); - await this.createDocumentTypeBtn.click(); + await this.click(this.createDocumentTypeBtn); } async clickCreateDocumentTypeWithTemplateButton() { - await expect(this.createDocumentTypeWithTemplateBtn).toBeVisible(); - await this.createDocumentTypeWithTemplateBtn.click(); + await this.click(this.createDocumentTypeWithTemplateBtn); } async clickCreateElementTypeButton() { - await expect(this.createElementTypeBtn).toBeVisible(); - await this.createElementTypeBtn.click(); + await this.click(this.createElementTypeBtn); } async clickCreateDocumentFolderButton() { - await expect(this.createDocumentFolderBtn).toBeVisible(); - await this.createDocumentFolderBtn.click(); + await this.click(this.createDocumentFolderBtn); } async isDocumentTreeItemVisible(name: string, isVisible = true) { - await expect(this.page.locator('umb-tree-item').locator('[label="' + name + '"]')).toBeVisible({visible: isVisible}); + await expect(this.page.locator('umb-tree-item').locator(`[label="${name}"]`)).toBeVisible({visible: isVisible}); } async clickSetAsDefaultButton() { - await expect(this.setAsDefaultBtn).toBeVisible(); - await this.setAsDefaultBtn.click(); + await this.click(this.setAsDefaultBtn); } async clickDocumentTypesMenu() { - await expect(this.documentTypesMenu).toBeVisible(); - await this.documentTypesMenu.click(); + await this.click(this.documentTypesMenu); } } \ No newline at end of file diff --git a/lib/helpers/ExamineManagementUiHelper.ts b/lib/helpers/ExamineManagementUiHelper.ts index 16d5b7e3..876c8c1f 100644 --- a/lib/helpers/ExamineManagementUiHelper.ts +++ b/lib/helpers/ExamineManagementUiHelper.ts @@ -16,11 +16,11 @@ export class ExamineManagementUiHelper extends UiBaseLocators { } async clickExamineManagementTab() { - await this.examineManagementTab.click(); + await this.click(this.examineManagementTab); } async doesIndexersHaveText(text: string) { - return await expect(this.indexersContent).toContainText(text); + await this.containsText(this.indexersContent, text); } checkIndexersCount() { @@ -28,7 +28,7 @@ export class ExamineManagementUiHelper extends UiBaseLocators { } async clickIndexByName(indexName: string) { - await this.page.getByRole('link', { name: indexName }).click(); + await this.click(this.page.getByRole('link', {name: indexName})); } async doesIndexPropertyHaveValue(indexProperty: string, indexValue: string) { @@ -36,6 +36,6 @@ export class ExamineManagementUiHelper extends UiBaseLocators { } async doesIndexHaveHealthStatus(indexName: string, status: string) { - return expect(this.page.locator("[headline='" + indexName + "']").getByText(status)).toBeVisible(); + return expect(this.page.locator(`[headline='${indexName}']`).getByText(status)).toBeVisible(); } } diff --git a/lib/helpers/FormsUiHelper.ts b/lib/helpers/FormsUiHelper.ts index a7102045..a7009a16 100644 --- a/lib/helpers/FormsUiHelper.ts +++ b/lib/helpers/FormsUiHelper.ts @@ -1,7 +1,8 @@ import { UiBaseLocators } from "./UiBaseLocators"; -import { expect, Locator, Page } from "@playwright/test" +import { Locator, Page } from "@playwright/test"; +import { ConstantHelper } from "./ConstantHelper"; -export class FormsUiHelper extends UiBaseLocators{ +export class FormsUiHelper extends UiBaseLocators { private readonly quickCreateNewBtn: Locator; private readonly createNewFormModalBtn: Locator; private readonly saveFormBtn: Locator; @@ -136,360 +137,328 @@ export class FormsUiHelper extends UiBaseLocators{ */ async clickQuickCreateFormButton() { - await this.formMenuItemForForm.hover(); - await this.formMenuItemForForm.locator(this.quickCreateNewBtn).click(); + await this.hoverAndClick(this.formMenuItemForForm, this.formMenuItemForForm.locator(this.quickCreateNewBtn)); } async clickNewFormButton() { - await expect(this.createNewFormModalBtn).toBeVisible(); - await this.createNewFormModalBtn.click(); + await this.click(this.createNewFormModalBtn); } - async clickSaveFormButton(){ - await this.saveFormBtn.click(); + async clickSaveFormButton() { + await this.click(this.saveFormBtn); } - async fillFormName(name: string){ - await expect(this.formNameTxt).toBeVisible(); - await this.formNameTxt.fill(name); + async fillFormName(name: string) { + await this.enterText(this.formNameTxt, name); } - async fillFormPageName(position: number, name: string){ + async fillFormPageName(position: number, name: string) { const nameInput = this.formPageNametxt.nth(position); - await expect(nameInput).toBeVisible(); - await nameInput.fill(name); + await this.enterText(nameInput, name); } - async fillFormGroupName(position: number, name: string){ + async fillFormGroupName(position: number, name: string) { const groupInput = this.formGroupNameTxt.nth(position); - await expect(groupInput).toBeVisible(); - await groupInput.fill(name); + await this.enterText(groupInput, name); } - async fillFormFieldName(name: string){ + async fillFormFieldName(name: string) { await this.formEditFieldModal.locator(this.formFieldNameTxt).fill(name); } - async clickAddNewPageButton(){ - await this.formAddNewPageBtn.click(); + async clickAddNewPageButton() { + await this.click(this.formAddNewPageBtn); } - async clickAddNewGroupButton(){ - await this.formAddNewGroupBtn.click(); + async clickAddNewGroupButton() { + await this.click(this.formAddNewGroupBtn); } - async clickAddQuestionButton(index: number = 0){ + async clickAddQuestionButton(index: number = 0) { const button = this.formPage.nth(index).locator(this.formAddQuestionBtn); - await button.click(); + await this.click(button); } - async chooseFormFieldType(type: string){ - await this.formFieldType.filter({hasText: type}).nth(0).click(); + async chooseFormFieldType(type: string) { + await this.click(this.formFieldType.filter({hasText: type}).nth(0)); } - async clickExpandFormsTreeButton(){ - await this.formExpandBtn.click(); + async clickExpandFormsTreeButton() { + await this.click(this.formExpandBtn); } async doesFormTreeHaveFormName(name: string) { - await expect(this.formTree).toContainText(name); + await this.containsText(this.formTree, name); } async goToFormWithName(name: string) { - await this.formTree.getByText(name, {exact: true}).click(); + await this.click(this.formTree.getByText(name, {exact: true})); } async clickFormFieldTypeSubmitModal() { - await this.formSubmitButtonModal.click(); + await this.click(this.formSubmitButtonModal); } - async clickActionMenuOnFormMenuItem(name: string){ - await this.menuItem.locator('[label="' + name + '"] uui-button[label="Open actions menu"]').click(); + async clickActionMenuOnFormMenuItem(name: string) { + await this.click(this.menuItem.locator(`[label="${name}"] uui-button[label="Open actions menu"]`)); } - async clickDeleteFormButton(){ - await this.formActionModal.locator(this.formDeleteThreeDotBtn).click(); - await this.deleteExactBtn.click(); + async clickDeleteFormButton() { + await this.click(this.formActionModal.locator(this.formDeleteThreeDotBtn)); + await this.click(this.deleteExactBtn); } - async goToFormSetting(){ - await this.formWorkspaceEditor.locator(this.formSettingIcon).click(); + async goToFormSetting() { + await this.click(this.formWorkspaceEditor.locator(this.formSettingIcon)); } - async setFormStoreRecordsSetting(){ - await expect(this.formSettingStoreRecordBtn).toBeVisible(); + async setFormStoreRecordsSetting() { + await this.waitForVisible(this.formSettingStoreRecordBtn); const toggle = this.formSettingStoreRecordBtn.locator(this.formToggleSlider); - await expect(toggle).toBeVisible(); + await this.waitForVisible(toggle); await toggle.check(); } - async setFormCaptionsSetting(){ - await expect(this.formSettingCaptionsContainer).toBeVisible(); + async setFormCaptionsSetting() { + await this.waitForVisible(this.formSettingCaptionsContainer); for (let i = 0; i < 3; i++) { const captionInput = this.formSettingCaptions.locator(this.formInputTxt).nth(i); - await expect(captionInput).toBeVisible(); - await captionInput.fill("Test Caption " + (i + 1)); + await this.enterText(captionInput, `Test Caption ${i + 1}`); } } - async setFormStylingSetting(){ - await expect(this.formSettingStylingContainer).toBeVisible(); + async setFormStylingSetting() { + await this.waitForVisible(this.formSettingStylingContainer); const cssClassInput = this.formSettingStyling.locator(this.formInputTxt); - await expect(cssClassInput).toBeVisible(); - await cssClassInput.fill("custom-css-class"); + await this.enterText(cssClassInput, "custom-css-class"); const disableDefaultStylesheetInput = this.formSettingStyling.locator(this.formToggleSlider); - await expect(disableDefaultStylesheetInput).toBeVisible(); - await disableDefaultStylesheetInput.click(); + await this.click(disableDefaultStylesheetInput); } - async setFormValidationSetting(){ - await expect(this.formSettingValidationContainer).toBeVisible(); + async setFormValidationSetting() { + await this.waitForVisible(this.formSettingValidationContainer); const requiredErrorMessageInput = this.formSettingValidation.locator(this.formInputTxt).nth(0); - await expect(requiredErrorMessageInput).toBeVisible(); - await requiredErrorMessageInput.fill("Required error message"); + await this.enterText(requiredErrorMessageInput, "Required error message"); const invalidErrorMessageInput = this.formSettingValidation.locator(this.formInputTxt).nth(1); - await expect(invalidErrorMessageInput).toBeVisible(); - await invalidErrorMessageInput.fill("Invalid error message"); + await this.enterText(invalidErrorMessageInput, "Invalid error message"); const showValidationSummaryInput = this.formSettingValidation.locator(this.formToggleSlider).nth(0); - await expect(showValidationSummaryInput).toBeVisible(); - await showValidationSummaryInput.click(); + await this.click(showValidationSummaryInput); const hideFieldValidationInput = this.formSettingValidation.locator(this.formToggleSlider).nth(1); - await expect(hideFieldValidationInput).toBeVisible(); - await hideFieldValidationInput.click(); + await this.click(hideFieldValidationInput); const markMandatoryFieldRadioInput = this.formSettingValidation.locator("uui-radio[value = 'MarkMandatoryFields']"); - await expect(markMandatoryFieldRadioInput).toBeVisible(); - await markMandatoryFieldRadioInput.click(); + await this.click(markMandatoryFieldRadioInput); const indicatorInput = this.formSettingValidation.locator(this.formInputTxt).nth(2); - await expect(indicatorInput).toBeVisible(); - await indicatorInput.fill("+"); + await this.enterText(indicatorInput, "+"); } - async setFormAutocompleteSetting(){ - await expect(this.formSettingAutocompleteContainer).toBeVisible(); + async setFormAutocompleteSetting() { + await this.waitForVisible(this.formSettingAutocompleteContainer); const autocompleteAttributeRadioInput = this.formSettingAutocomplete.locator('uui-radio[value = "On"]'); - await expect(autocompleteAttributeRadioInput).toBeVisible(); - await autocompleteAttributeRadioInput.click(); + await this.click(autocompleteAttributeRadioInput); } - async setFormModerationSetting(){ - await expect(this.formSettingModerationContainer).toBeVisible(); + async setFormModerationSetting() { + await this.waitForVisible(this.formSettingModerationContainer); const enablePostModerationAttributeToggleInput = this.formSettingModeration.locator(this.formToggleSlider); - await expect(enablePostModerationAttributeToggleInput).toBeVisible(); - await enablePostModerationAttributeToggleInput.click(); + await this.click(enablePostModerationAttributeToggleInput); } - async setFormFieldsDisplayedSetting(){ - await expect(this.formSettingFieldsDisplayedContainer).toBeVisible(); + async setFormFieldsDisplayedSetting() { + await this.waitForVisible(this.formSettingFieldsDisplayedContainer); const displayDefaultFieldsToggleInput = this.formSettingFieldsDisplayed.locator(this.formToggleSlider); - await expect(displayDefaultFieldsToggleInput).toBeVisible(); - await displayDefaultFieldsToggleInput.click(); - await this.page.waitForTimeout(100); // short pause required here otherwise revealed elements are not found + await this.click(displayDefaultFieldsToggleInput); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); // short pause required here otherwise revealed elements are not found const displayFieldsSelect = this.formSettingFieldsDisplayed.locator("select"); - await expect(displayFieldsSelect).toBeVisible(); - await displayFieldsSelect.selectOption({ value: '_system_state' }); + await this.selectByValue(displayFieldsSelect, '_system_state'); const displayFieldsAddButton = this.formSettingFieldsDisplayed.locator("button[id='button']"); - await expect(displayFieldsAddButton).toBeVisible(); - await displayFieldsAddButton.click(); + await this.click(displayFieldsAddButton); } - async setFormDataRetentionSetting(recordNumber: string){ - await expect(this.formSettingDataRetentionContainer).toBeVisible(); + async setFormDataRetentionSetting(recordNumber: string) { + await this.waitForVisible(this.formSettingDataRetentionContainer); const retainSubmittedRecordsToggleInput = this.formSettingDataRetention.locator(this.formToggleSlider).nth(0); - await expect(retainSubmittedRecordsToggleInput).toBeVisible(); - await retainSubmittedRecordsToggleInput.click(); - await this.page.waitForTimeout(100); // short pause required here otherwise revealed elements are not found + await this.click(retainSubmittedRecordsToggleInput); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); // short pause required here otherwise revealed elements are not found const retainSubmittedRecordsNumberInput = this.formSettingDataRetention.locator(this.formInputNumber).nth(0); - await expect(retainSubmittedRecordsNumberInput).toBeVisible(); - await retainSubmittedRecordsNumberInput.fill(recordNumber); + await this.enterText(retainSubmittedRecordsNumberInput, recordNumber); } async toggleFieldSetting(settingAlias: string) { - const settingFieldLocator = this.page.locator('umb-property-layout[alias="' + settingAlias + '"] #toggle'); - await expect(settingFieldLocator).toBeVisible(); - await settingFieldLocator.click(); + const settingFieldLocator = this.page.locator(`umb-property-layout[alias="${settingAlias}"] #toggle`); + await this.click(settingFieldLocator); } async applyFieldSettingViaTextInput(settingAlias: string, settingValue: string) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"] input'); + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"] input`); await settingFieldLocator.fill(settingValue); } async applyFieldSettingViaDropDown(settingAlias: string, settingValue: string) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"] select'); - await settingFieldLocator.selectOption({ value: settingValue }); + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"] select`); + await this.selectByValue(settingFieldLocator, settingValue); } async applyFieldSettingViaSlider(settingAlias: string) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"] #toggle'); - await expect(settingFieldLocator).toBeVisible(); - await settingFieldLocator.click(); + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"] #toggle`); + await this.click(settingFieldLocator); } async applyFieldFileUploadSettings(settingAlias: string, allowedProvidedExtensions: Array, allowedCustomExtensions: Array, allowMultiple: boolean) { - const settingFieldLocator = this.page.locator('umb-property-layout[alias="' + settingAlias + '"]'); + const settingFieldLocator = this.page.locator(`umb-property-layout[alias="${settingAlias}"]`); for (var i = 0; i < allowedProvidedExtensions.length; i++) { const checkBoxLocator = settingFieldLocator.locator('uui-toggle', {hasText: allowedProvidedExtensions[i].toUpperCase()}).locator('#toggle'); - await expect(checkBoxLocator).toBeVisible(); - await checkBoxLocator.click(); + await this.click(checkBoxLocator); } - + const addNewExtensionLocator = settingFieldLocator.locator('input[placeholder = "Add new allowed file type"]'); - await expect(addNewExtensionLocator).toBeVisible(); + await this.waitForVisible(addNewExtensionLocator); const buttonLocator = settingFieldLocator.locator('form svg'); - await expect(buttonLocator).toBeVisible(); + await this.waitForVisible(buttonLocator); for (var i = 0; i < allowedCustomExtensions.length; i++) { await addNewExtensionLocator.fill(allowedCustomExtensions[i]); - await buttonLocator.click(); + await this.click(buttonLocator); } - + if (allowMultiple) { const alias = "allowMultipleFileUploads"; - const multipleUploadLocator = this.page.locator('umb-property-layout[alias="' + alias + '"] #toggle'); - await expect(multipleUploadLocator).toBeVisible(); - await multipleUploadLocator.click(); + const multipleUploadLocator = this.page.locator(`umb-property-layout[alias="${alias}"] #toggle`); + await this.click(multipleUploadLocator); } } async applyFieldPrevalues(settingAlias: string, prevalues: Array) { - const settingFieldLocator = this.page.locator('umb-property-layout[alias="' + settingAlias + '"]'); + const settingFieldLocator = this.page.locator(`umb-property-layout[alias="${settingAlias}"]`); for (var i = 0; i < prevalues.length; i++) { const valueFieldLocator = settingFieldLocator.locator("input[placeholder = 'New value']"); - await expect(valueFieldLocator).toBeVisible(); + await this.waitForVisible(valueFieldLocator); await valueFieldLocator.fill(prevalues[i].value); - + const captionFieldLocator = settingFieldLocator.locator("input[placeholder = 'New caption']"); - await expect(captionFieldLocator).toBeVisible(); + await this.waitForVisible(captionFieldLocator); await captionFieldLocator.fill(prevalues[i].caption); - + const buttonLocator = settingFieldLocator.locator('uui-button[label="add"]'); - await expect(buttonLocator).toBeVisible(); - await buttonLocator.click(); + await this.click(buttonLocator); } } async applyFieldSettingViaTextArea(settingAlias: string, settingValue: string) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"] textarea'); + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"] textarea`); await settingFieldLocator.fill(settingValue); } async applyFieldSettingViaRichTextInput(settingAlias: string, settingValue: string) { - const richTextAreaTxt = this.page.locator('umb-property[alias="' + settingAlias + '"] umb-property-editor-ui-tiptap').locator('#editor .tiptap'); - await expect(richTextAreaTxt).toBeVisible(); + const richTextAreaTxt = this.page.locator(`umb-property[alias="${settingAlias}"] umb-property-editor-ui-tiptap`).locator('#editor .tiptap'); + await this.waitForVisible(richTextAreaTxt); await richTextAreaTxt.fill(settingValue); } async applyFieldSettingViaRange(settingAlias: string, settingValue: string) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"]'); + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"]`); await settingFieldLocator.locator('input[type="range"]').fill(settingValue); } async applyFieldSettingViaFieldMappingInput(settingAlias: string, settingValue: Array) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"]'); - await expect(settingFieldLocator).toBeVisible(); - + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"]`); + await this.waitForVisible(settingFieldLocator); + for (let i = 0; i < settingValue.length; i++) { const buttonLocator = settingFieldLocator.locator('uui-button[label="add"]'); - await expect(buttonLocator).toBeVisible(); - await buttonLocator.click(); - + await this.click(buttonLocator); + const aliasInputLocator = settingFieldLocator.locator("input[placeholder = 'Alias']").nth(i); - await expect(aliasInputLocator).toBeVisible(); + await this.waitForVisible(aliasInputLocator); await aliasInputLocator.fill(settingValue[i].alias); - + const staticValueInputLocator = settingFieldLocator.locator("input[placeholder = 'Static value']").nth(i); - await expect(staticValueInputLocator).toBeVisible(); + await this.waitForVisible(staticValueInputLocator); await staticValueInputLocator.fill(settingValue[i].staticValue); } } async applyFieldSettingViaDocumentMapper(settingAlias: string, settingValue: any) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"]'); - await expect(settingFieldLocator).toBeVisible(); - + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"]`); + await this.waitForVisible(settingFieldLocator); + const selectLocator = settingFieldLocator.locator("forms-document-mapper-property-editor select"); - await selectLocator.selectOption({ value : settingValue.doctype }); - + await this.selectByValue(selectLocator, settingValue.doctype); + const inputLocator = settingFieldLocator.locator('forms-document-mapper-property-editor input[type = "text"]'); - await expect(inputLocator.first()).toBeVisible(); + await this.waitForVisible(inputLocator.first()); const inputLocatorCount = await inputLocator.count(); for (let i = 0; i < inputLocatorCount; i++) { - await expect(inputLocator.nth(i)).toBeVisible(); + await this.waitForVisible(inputLocator.nth(i)); await inputLocator.nth(i).fill(settingValue.nameStaticValue); } } async applyFieldSettingViaEmailTemplatePicker(settingAlias: string, settingValue: string) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"]'); - await expect(settingFieldLocator).toBeVisible(); - + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"]`); + await this.waitForVisible(settingFieldLocator); + const buttonLocator = settingFieldLocator.locator("#caret-button"); - await buttonLocator.click(); - + await this.click(buttonLocator); + const templateLocator = this.page.locator("#label-button", {hasText: settingValue}); - await expect(templateLocator).toBeVisible(); - await templateLocator.click(); + await this.click(templateLocator); } async applyFieldSettingViaStandardFieldMappingInput(settingAlias: string, settingValue: Array) { - const settingFieldLocator = this.page.locator('umb-property[alias="' + settingAlias + '"]'); - await expect(settingFieldLocator).toBeVisible(); - + const settingFieldLocator = this.page.locator(`umb-property[alias="${settingAlias}"]`); + await this.waitForVisible(settingFieldLocator); + for (let i = 0; i < settingValue.length; i++) { if (settingValue[i].include) { - const includeButtonLocator = settingFieldLocator.locator('div[data-umb-standard-field-mapping-include="' + settingValue[i].alias + '"] #toggle'); - await includeButtonLocator.click(); + const includeButtonLocator = settingFieldLocator.locator(`div[data-umb-standard-field-mapping-include="${settingValue[i].alias}"] #toggle`); + await this.click(includeButtonLocator); } - - const keyNameButtonLocator = settingFieldLocator.locator('div[data-umb-standard-field-mapping-key-name="' + settingValue[i].alias + '"] input[type="text"]'); + + const keyNameButtonLocator = settingFieldLocator.locator(`div[data-umb-standard-field-mapping-key-name="${settingValue[i].alias}"] input[type="text"]`); await keyNameButtonLocator.fill(settingValue[0].keyName); } } async setFieldMandatory(message: string) { - await expect(this.formFieldMandatory).toBeVisible(); - await this.formFieldMandatory.locator("#toggle").click(); - await this.page.waitForTimeout(1000); + await this.click(this.formFieldMandatory.locator("#toggle")); + await this.page.waitForTimeout(ConstantHelper.wait.medium); const inputLocator = this.formFieldMandatory.locator(this.formInputTxt); - await expect(inputLocator).toBeVisible(); - await inputLocator.fill(message); + await this.enterText(inputLocator, message); } - + async setFieldValidation(label: string, message: string) { - await expect(this.formFieldRegex).toBeVisible(); + await this.waitForVisible(this.formFieldRegex); const selectLocator = this.formFieldRegex.locator("select"); - await selectLocator.selectOption({ label: label }); - await this.page.waitForTimeout(1000); + await this.selectByText(selectLocator, label); + await this.page.waitForTimeout(ConstantHelper.wait.medium); const inputLocator = this.formFieldRegex.locator("input"); - await expect(inputLocator).toBeVisible(); - await inputLocator.fill(message); + await this.enterText(inputLocator, message); } - async clickFormWorkflowConfigureButton(){ - await this.formWorkflowConfigureBtn.click(); + async clickFormWorkflowConfigureButton() { + await this.click(this.formWorkflowConfigureBtn); } async clickFormWorkflowEditSubmitButton() { - await this.formEditWorkflowModal.locator(this.formSubmitButtonModal).click(); + await this.click(this.formEditWorkflowModal.locator(this.formSubmitButtonModal)); } async clickFormWorkflowConfigureSubmitButton() { - await this.formConfigureWorkflowModal.locator(this.formSubmitButtonModal).click(); + await this.click(this.formConfigureWorkflowModal.locator(this.formSubmitButtonModal)); } - async clickFormWorkflowAddButton(){ - await this.formWorkflowOnSubmitStage.locator(this.formWorkflowAddButtonModal).click({force: true}); + async clickFormWorkflowAddButton() { + await this.click(this.formWorkflowOnSubmitStage.locator(this.formWorkflowAddButtonModal), {force: true}); } - async selectWorkflowType(workflowType: string){ - this.page.locator('umb-ref-item[title="' + workflowType + '"]').click(); + async selectWorkflowType(workflowType: string) { + await this.click(this.page.locator(`umb-ref-item[title="${workflowType}"]`)); } async fillWorkflowName(workflowName: string) { - await expect(this.formWorkflowNameTxt).toBeVisible(); - await this.formWorkflowNameTxt.fill(workflowName); + await this.enterText(this.formWorkflowNameTxt, workflowName); } /* @@ -497,61 +466,54 @@ export class FormsUiHelper extends UiBaseLocators{ */ async clickQuickCreatePrevalueSourceButton() { - await expect(this.formMenuItemForPrevalueSource).toBeVisible(); - await this.formMenuItemForPrevalueSource.hover(); - await this.formMenuItemForPrevalueSource.locator(this.quickCreateNewBtn).click(); + await this.hoverAndClick(this.formMenuItemForPrevalueSource, this.formMenuItemForPrevalueSource.locator(this.quickCreateNewBtn)); } async clickPrevalueSourceTypeButton(type: string) { const button = this.createNewPrevaluesourceModalBtn.locator("#name", {hasText: type}); - await expect(button).toBeVisible(); - await button.click(); + await this.click(button); } - async clickExpandPrevalueSourceTreeButton(){ - await this.prevalueSourceExpandBtn.click(); + async clickExpandPrevalueSourceTreeButton() { + await this.click(this.prevalueSourceExpandBtn); } async goToPrevalueSourceWithName(name: string) { - await this.prevalueSourceTree.locator('uui-menu-item[label="' + name + '"]').click(); + await this.click(this.prevalueSourceTree.locator(`uui-menu-item[label="${name}"]`)); } - async clickDeletePrevalueSourceButton(name: string){ - const prevalueSource = await this.prevalueSourceTree.locator('uui-menu-item[label="' + name + '"]'); - await prevalueSource.locator(this.prevalueSourceDeleteBtn).click(); - await this.deleteExactBtn.click(); + async clickDeletePrevalueSourceButton(name: string) { + const prevalueSource = this.prevalueSourceTree.locator(`uui-menu-item[label="${name}"]`); + await this.click(prevalueSource.locator(this.prevalueSourceDeleteBtn)); + await this.click(this.deleteExactBtn); } async applyCacheOptions(option: string, timeValue: number = 0, timeUnit: string = "") { - await expect(this.prevalueSourceCacheContainer).toBeVisible(); - const optionSelect = this.prevalueSourceCacheContainer.locator('uui-radio[value = "' + option + '"]'); - await expect(optionSelect).toBeVisible(); - await optionSelect.click(); - + await this.waitForVisible(this.prevalueSourceCacheContainer); + const optionSelect = this.prevalueSourceCacheContainer.locator(`uui-radio[value = "${option}"]`); + await this.click(optionSelect); + if (option === "time") { const numberInput = this.prevalueSourceCacheContainer.locator("input[type='number']"); - await expect(numberInput).toBeVisible(); + await this.waitForVisible(numberInput); await numberInput.fill(timeValue.toString()); - + const unitSelect = this.prevalueSourceCacheContainer.locator("select"); - await expect(unitSelect).toBeVisible(); - await unitSelect.selectOption({ value: timeUnit }); + await this.selectByValue(unitSelect, timeUnit); } } async applyPrevalueSourceSettingViaNodeSelector(labelText: string, settingValue: string) { - const container = this.page.locator('umb-property[alias="' + labelText + '"]'); - await expect(container).toBeVisible(); + const container = this.page.locator(`umb-property[alias="${labelText}"]`); + await this.waitForVisible(container); const rootNode = container.locator('uui-button[label="Specify root node"]'); - await expect(rootNode).toBeVisible(); - await rootNode.click(); - await expect(this.prevalueSourceOriginModal).toBeVisible(); - const value = this.prevalueSourceOriginModal.locator('umb-ref-item[name="' + settingValue + '"]'); - await expect(value).toBeVisible(); - await value.click(); + await this.click(rootNode); + await this.waitForVisible(this.prevalueSourceOriginModal); + const value = this.prevalueSourceOriginModal.locator(`umb-ref-item[name="${settingValue}"]`); + await this.click(value); } - async checkPrevalueSourceTypeLabel(){ - await expect(this.prevalueSourceTypeLabel).toBeVisible(); + async checkPrevalueSourceTypeLabel() { + await this.waitForVisible(this.prevalueSourceTypeLabel); } } \ No newline at end of file diff --git a/lib/helpers/HealthCheckUiHelper.ts b/lib/helpers/HealthCheckUiHelper.ts index ca65335f..29495f39 100644 --- a/lib/helpers/HealthCheckUiHelper.ts +++ b/lib/helpers/HealthCheckUiHelper.ts @@ -24,7 +24,7 @@ export class HealthCheckUiHelper extends UiBaseLocators { } async clickHealthCheckTab() { - await this.healthCheckTab.click(); + await this.click(this.healthCheckTab); } async checkHealthCheckGroupCount() { @@ -33,11 +33,11 @@ export class HealthCheckUiHelper extends UiBaseLocators { } async clickPerformanceAllChecksButton() { - await this.performanceAllChecksBtn.click(); + await this.click(this.performanceAllChecksBtn); } async clickHeathCheckGroupByName(groupName: string) { - await this.page.getByRole('link', { name: groupName }).click(); + await this.click(this.page.getByRole('link', {name: groupName})); } async isHealthCheckGroupVisible(groupName: string) { diff --git a/lib/helpers/LanguageUiHelper.ts b/lib/helpers/LanguageUiHelper.ts index 5b544a06..45b2bf0b 100644 --- a/lib/helpers/LanguageUiHelper.ts +++ b/lib/helpers/LanguageUiHelper.ts @@ -27,13 +27,11 @@ export class LanguageUiHelper extends UiBaseLocators { } async clickLanguageCreateButton() { - await expect(this.languageCreateBtn).toBeVisible(); - await this.languageCreateBtn.click(); + await this.click(this.languageCreateBtn); } async clickLanguagesMenu() { - await expect(this.languagesMenu).toBeVisible(); - await this.languagesMenu.click(); + await this.click(this.languagesMenu); } async goToLanguages() { @@ -42,26 +40,26 @@ export class LanguageUiHelper extends UiBaseLocators { } async waitForLanguageToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForLanguageToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } - + async removeFallbackLanguageByIsoCode(isoCode: string) { - await this.page.locator('umb-entity-item-ref[id="' + isoCode + '"]').hover(); - await this.page.locator('umb-entity-item-ref[id="' + isoCode + '"]').getByLabel('Remove').click(); - await this.confirmToRemoveBtn.click(); + const languageLocator = this.page.locator(`umb-entity-item-ref[id="${isoCode}"]`); + await this.hoverAndClick(languageLocator, languageLocator.getByLabel('Remove')); + await this.click(this.confirmToRemoveBtn); } async chooseLanguageByName(name: string) { - await this.languageDropdown.click(); - await this.page.locator('umb-input-culture-select').getByText(name, {exact: true}).click(); + await this.click(this.languageDropdown); + await this.click(this.page.locator('umb-input-culture-select').getByText(name, {exact: true})); } async clickLanguageByName(name: string) { - await this.languageTable.getByText(name, {exact: true}).click(); + await this.click(this.languageTable.getByText(name, {exact: true})); } async isLanguageNameVisible(name: string, isVisible = true) { @@ -69,19 +67,19 @@ export class LanguageUiHelper extends UiBaseLocators { } async switchDefaultLanguageOption() { - await this.defaultLanguageToggle.click(); + await this.click(this.defaultLanguageToggle); } async switchMandatoryLanguageOption() { - await this.mandatoryLanguageToggle.click(); + await this.click(this.mandatoryLanguageToggle); } async clickAddFallbackLanguageButton() { - await this.addFallbackLanguageBtn.click(); + await this.click(this.addFallbackLanguageBtn); } async clickRemoveLanguageByName(name: string) { - await this.page.locator('uui-table-row').filter({has: this.page.getByText(name, {exact: true})}).locator(this.deleteLanguageEntityAction).click({force: true}); + await this.click(this.page.locator('uui-table-row').filter({has: this.page.getByText(name, {exact: true})}).locator(this.deleteLanguageEntityAction), {force: true}); } async removeLanguageByName(name: string) { @@ -90,7 +88,7 @@ export class LanguageUiHelper extends UiBaseLocators { } async selectFallbackLanguageByName(name: string) { - await this.page.locator('umb-language-picker-modal').getByLabel(name).click(); + await this.click(this.page.locator('umb-language-picker-modal').getByLabel(name)); await this.clickSubmitButton(); } } \ No newline at end of file diff --git a/lib/helpers/LogViewerUiHelper.ts b/lib/helpers/LogViewerUiHelper.ts index 13a3a0f6..1c423113 100644 --- a/lib/helpers/LogViewerUiHelper.ts +++ b/lib/helpers/LogViewerUiHelper.ts @@ -34,28 +34,24 @@ export class LogViewerUiHelper extends UiBaseLocators { } async clickSearchButton() { - await expect(this.searchBtn).toBeVisible(); - await this.searchBtn.click(); - await expect(this.searchLogsTxt).toBeVisible(); + await this.click(this.searchBtn); + await this.waitForVisible(this.searchLogsTxt); } async clickOverviewButton() { - await expect(this.overviewBtn).toBeVisible(); - await this.overviewBtn.click(); + await this.click(this.overviewBtn); } async enterSearchKeyword(keyword: string) { - await this.searchLogsTxt.clear(); - await this.searchLogsTxt.fill(keyword); + await this.enterText(this.searchLogsTxt, keyword); } async selectLogLevel(level: string) { - await expect(this.selectLogLevelBtn).toBeVisible(); // The force click is necessary. - await this.selectLogLevelBtn.click({force: true}); + await this.click(this.selectLogLevelBtn, {force: true}); const logLevelLocator = this.page.locator('.log-level-menu-item').getByText(level); - await expect(logLevelLocator).toBeVisible(); - await logLevelLocator.click({force: true}); + // Force click is needed + await this.click(logLevelLocator, {force: true}); } async doesLogLevelIndicatorDisplay(level: string) { @@ -63,16 +59,14 @@ export class LogViewerUiHelper extends UiBaseLocators { } async doesLogLevelCountMatch(level: string, expectedNumber: number) { - return await expect(this.page.locator('umb-log-viewer-message').locator('umb-log-viewer-level-tag', {hasText: level})).toHaveCount(expectedNumber); + await this.hasCount(this.page.locator('umb-log-viewer-message').locator('umb-log-viewer-level-tag', {hasText: level}), expectedNumber); } async saveSearch(searchName: string) { - await expect(this.saveSearchHeartIcon).toBeVisible(); // The force click is necessary. - await this.saveSearchHeartIcon.click({force: true}); - await this.searchNameTxt.clear(); - await this.searchNameTxt.fill(searchName); - await this.saveSearchBtn.click(); + await this.click(this.saveSearchHeartIcon, {force: true}); + await this.enterText(this.searchNameTxt, searchName); + await this.click(this.saveSearchBtn); } checkSavedSearch(searchName: string) { @@ -80,24 +74,23 @@ export class LogViewerUiHelper extends UiBaseLocators { } async clickSortLogByTimestampButton() { - await this.sortLogByTimestampBtn.click(); + await this.click(this.sortLogByTimestampBtn); } async doesFirstLogHaveTimestamp(timestamp: string) { - return await expect(this.firstLogLevelTimestamp).toContainText(timestamp); + await this.containsText(this.firstLogLevelTimestamp, timestamp); } async clickPageNumber(pageNumber: number) { - await this.page.getByLabel('Go to page ' + pageNumber, {exact: true}).click(); + await this.click(this.page.getByLabel(`Go to page ${pageNumber}`, {exact: true})); } async doesFirstLogHaveMessage(message: string) { - await expect(this.firstLogLevelMessage).toContainText(message, {timeout: 10000}); + await this.containsText(this.firstLogLevelMessage, message, 10000); } async clickSavedSearchByName(name: string) { - await expect(this.page.locator('#saved-searches').getByLabel(name)).toBeVisible(); - await this.page.locator('#saved-searches').getByLabel(name).click(); + await this.click(this.page.locator('#saved-searches').getByLabel(name)); } async doesSearchBoxHaveValue(searchValue: string) { @@ -105,7 +98,7 @@ export class LogViewerUiHelper extends UiBaseLocators { } async clickFirstLogSearchResult() { - await this.firstLogSearchResult.click(); + await this.click(this.firstLogSearchResult); } async doesDetailedLogHaveText(text: string) { @@ -113,19 +106,17 @@ export class LogViewerUiHelper extends UiBaseLocators { } async clickSavedSearchesButton() { - await expect(this.savedSearchesBtn).toBeVisible(); // The force click is necessary. - await this.savedSearchesBtn.click({force: true}); + await this.click(this.savedSearchesBtn, {force: true}); } async removeSavedSearchByName(name: string) { const removedSavedSearchWithNameLocator = this.page.locator('.saved-search-item').filter({hasText: name}).getByLabel('Delete this search'); - await expect(removedSavedSearchWithNameLocator).toBeVisible(); // The force click is necessary. - await removedSavedSearchWithNameLocator.click({force: true}); + await this.click(removedSavedSearchWithNameLocator, {force: true}); } async waitUntilLoadingSpinnerInvisible() { - await expect(this.loadingSpinner).toHaveCount(0); + await this.hasCount(this.loadingSpinner, 0); } } diff --git a/lib/helpers/LoginUiHelper.ts b/lib/helpers/LoginUiHelper.ts index fa2e5f19..33eb71e6 100644 --- a/lib/helpers/LoginUiHelper.ts +++ b/lib/helpers/LoginUiHelper.ts @@ -1,5 +1,6 @@ -import {Page, Locator, expect} from "@playwright/test"; +import {Page, Locator} from "@playwright/test"; import {UiBaseLocators} from "./UiBaseLocators"; +import {ConstantHelper} from "./ConstantHelper"; export class LoginUiHelper extends UiBaseLocators { private readonly emailTxt: Locator; @@ -10,21 +11,19 @@ export class LoginUiHelper extends UiBaseLocators { super(page); this.emailTxt = page.locator('[name="username"]'); this.passwordTxt = page.locator('[name="password"]'); - this.loginBtn = page.getByLabel('Login'); + this.loginBtn = page.getByLabel('Login'); } async enterEmail(email: string) { - await expect(this.emailTxt).toBeVisible({timeout: 20000}); - await this.emailTxt.clear(); - await this.emailTxt.fill(email); + await this.waitForVisible(this.emailTxt, ConstantHelper.timeout.navigation); + await this.enterText(this.emailTxt, email); } async enterPassword(password: string) { - await this.passwordTxt.clear(); - await this.passwordTxt.fill(password); + await this.enterText(this.passwordTxt, password); } async clickLoginButton() { - await this.loginBtn.click(); + await this.click(this.loginBtn); } } diff --git a/lib/helpers/MediaTypeUiHelper.ts b/lib/helpers/MediaTypeUiHelper.ts index b146a1fd..290c495f 100644 --- a/lib/helpers/MediaTypeUiHelper.ts +++ b/lib/helpers/MediaTypeUiHelper.ts @@ -1,5 +1,5 @@ import {UiBaseLocators} from "./UiBaseLocators"; -import {expect, Locator, Page} from "@playwright/test"; +import {Locator, Page} from "@playwright/test"; export class MediaTypeUiHelper extends UiBaseLocators { private readonly newMediaTypeThreeDotsBtn: Locator; @@ -30,31 +30,29 @@ export class MediaTypeUiHelper extends UiBaseLocators { } async clickNewMediaTypeButton() { - await this.newMediaTypeThreeDotsBtn.click(); + await this.click(this.newMediaTypeThreeDotsBtn); } async isMediaTypeTreeItemVisible(name: string, isVisible: boolean = true) { - { - const hasShowChildren = await this.mediaTypeTreeRoot.getAttribute('show-children') !== null; + const hasShowChildren = await this.mediaTypeTreeRoot.getAttribute('show-children') !== null; - if (!hasShowChildren) { - await this.mediaTypeTreeRoot.locator(this.caretBtn).first().click(); - } - - await this.isTreeItemVisible(name, isVisible); + if (!hasShowChildren) { + await this.click(this.mediaTypeTreeRoot.locator(this.caretBtn).first()); } + + await this.isTreeItemVisible(name, isVisible); } async waitForMediaTypeToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForMediaTypeToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForMediaTypeToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } @@ -64,8 +62,7 @@ export class MediaTypeUiHelper extends UiBaseLocators { } async enterMediaTypeName(name: string) { - await this.enterAName.waitFor({state: 'visible'}); - await this.enterAName.fill(name); + await this.enterText(this.enterAName, name); } async enterDescriptionForPropertyEditorWithName(propertyEditorName: string, description: string) { @@ -73,12 +70,10 @@ export class MediaTypeUiHelper extends UiBaseLocators { } async clickMediaTypeButton() { - await expect(this.mediaTypeBtn).toBeVisible(); - await this.mediaTypeBtn.click(); + await this.click(this.mediaTypeBtn); } async clickMediaTypesMenu() { - await expect(this.mediaTypesMenu).toBeVisible(); - await this.mediaTypesMenu.click(); + await this.click(this.mediaTypesMenu); } } diff --git a/lib/helpers/MediaUiHelper.ts b/lib/helpers/MediaUiHelper.ts index 40e7eb0b..8741eded 100644 --- a/lib/helpers/MediaUiHelper.ts +++ b/lib/helpers/MediaUiHelper.ts @@ -1,5 +1,6 @@ import {UiBaseLocators} from "./UiBaseLocators"; import {expect, Locator, Page} from "@playwright/test"; +import {ConstantHelper} from "./ConstantHelper"; export class MediaUiHelper extends UiBaseLocators { private readonly createMediaItemBtn: Locator; @@ -50,58 +51,54 @@ export class MediaUiHelper extends UiBaseLocators { } async clickCreateMediaItemButton() { - await this.createMediaItemBtn.click(); + await this.click(this.createMediaItemBtn); } async enterMediaItemName(name: string) { - await expect(this.mediaNameTxt).toBeVisible(); - await this.mediaNameTxt.clear(); - await this.mediaNameTxt.fill(name); - await expect(this.mediaNameTxt).toHaveValue(name); + await this.enterText(this.mediaNameTxt, name, {verify: true}); } async clickMediaTypeWithNameButton(mediaTypeName: string) { - await this.page.getByLabel(mediaTypeName, {exact: true}).click(); + await this.click(this.page.getByLabel(mediaTypeName, {exact: true})); } async searchForMediaItemByName(name: string) { - await this.mediaSearchTxt.clear(); - await this.mediaSearchTxt.fill(name); + await this.enterText(this.mediaSearchTxt, name); } async doesMediaCardsContainAmount(count: number) { - await expect(this.mediaCardItems).toHaveCount(count); + await this.hasCount(this.mediaCardItems, count); } async doesMediaCardContainText(name: string) { - await expect(this.mediaCardItems).toContainText(name); + await this.containsText(this.mediaCardItems, name); } async clickTrashButton() { - await this.trashBtn.click(); + await this.click(this.trashBtn); } async restoreMediaItem(name: string) { await this.clickActionsMenuForName(name); - await this.restoreThreeDotsBtn.click(); - await this.page.waitForTimeout(1000); + await this.click(this.restoreThreeDotsBtn); + await this.page.waitForTimeout(ConstantHelper.wait.medium); await this.clickRestoreButton(); } async waitForMediaToBeTrashed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForRecycleBinToBeEmptied() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForMediaToBeMoved() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForMediaItemToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async deleteMediaItem(name: string) { @@ -111,40 +108,37 @@ export class MediaUiHelper extends UiBaseLocators { } async clickCreateMediaWithType(mediaTypeName: string) { - await expect(this.mediaCreateBtn).toBeVisible(); - await this.mediaCreateBtn.click(); + await this.click(this.mediaCreateBtn); await this.clickMediaTypeInPopoverByName(mediaTypeName); } async clickMediaTypeName(mediaTypeName: string) { - await this.documentTypeNode.filter({hasText: mediaTypeName}).click(); + await this.click(this.documentTypeNode.filter({hasText: mediaTypeName})); } async clickMediaTypeInPopoverByName(mediaTypeName: string) { - await this.mediaPopoverLayout.getByLabel(mediaTypeName).click(); + await this.click(this.mediaPopoverLayout.getByLabel(mediaTypeName)); } async clickEmptyRecycleBinButton() { - await this.recycleBinMenuItem.hover(); - await expect(this.emptyRecycleBinBtn).toBeVisible(); // Force click is needed - await this.emptyRecycleBinBtn.click({force: true}); + await this.hoverAndClick(this.recycleBinMenuItem, this.emptyRecycleBinBtn, {force: true}); } async clickConfirmEmptyRecycleBinButton() { - await this.confirmEmptyRecycleBinBtn.click(); + await this.click(this.confirmEmptyRecycleBinBtn); } async clickCreateModalButton() { - await this.actionModalCreateBtn.click(); + await this.click(this.actionModalCreateBtn); } async clickMediaCaretButtonForName(name: string) { - await this.page.locator('umb-media-tree-item [label="' + name + '"]').locator('#caret-button').click(); + await this.click(this.page.locator(`umb-media-tree-item [label="${name}"]`).locator('#caret-button')); } async openMediaCaretButtonForName(name: string) { - const menuItem = this.page.locator('umb-media-tree-item [label="' + name + '"]') + const menuItem = this.page.locator(`umb-media-tree-item [label="${name}"]`); const isCaretButtonOpen = await menuItem.getAttribute('show-children'); if (isCaretButtonOpen === null) { @@ -171,34 +165,32 @@ export class MediaUiHelper extends UiBaseLocators { } async isMediaGridViewVisible(isVisible: boolean = true) { - return expect(this.mediaGridView).toBeVisible({visible: isVisible}); + await this.isVisible(this.mediaGridView, isVisible); } async isMediaListViewVisible(isVisible: boolean = true) { - return expect(this.mediaListView).toBeVisible({visible: isVisible}); + await this.isVisible(this.mediaListView, isVisible); } async doesMediaWorkspaceHaveText(text: string) { - return expect(this.mediaWorkspace).toContainText(text); + await this.containsText(this.mediaWorkspace, text); } async clickBulkTrashButton() { - await this.bulkTrashBtn.click(); + await this.click(this.bulkTrashBtn); } async clickBulkMoveToButton() { - await this.bulkMoveToBtn.click(); + await this.click(this.bulkMoveToBtn); } async clickModalTextByName(name: string) { - await this.sidebarModal.getByLabel(name, {exact: true}).click(); + await this.click(this.sidebarModal.getByLabel(name, {exact: true})); } async reloadMediaTree() { - await expect(this.mediaHeader).toBeVisible(); - await this.mediaHeader.click(); - await expect(this.mediaHeaderActionsMenu).toBeVisible(); - await this.mediaHeaderActionsMenu.click({force: true}); + await this.click(this.mediaHeader); + await this.click(this.mediaHeaderActionsMenu, {force: true}); await this.clickReloadChildrenActionMenuOption(); } @@ -207,8 +199,8 @@ export class MediaUiHelper extends UiBaseLocators { } async doesMediaItemInTreeHaveThumbnail(name: string, thumbnailIconName: string) { - const mediaThumbnailIconLocator = this.page.locator('umb-media-tree-item [label="' + name + '"]').locator('#icon-container #icon'); - await expect(mediaThumbnailIconLocator).toHaveAttribute('name', thumbnailIconName); + const mediaThumbnailIconLocator = this.page.locator(`umb-media-tree-item [label="${name}"]`).locator('#icon-container #icon'); + await this.hasAttribute(mediaThumbnailIconLocator, 'name', thumbnailIconName); } async isChildMediaVisible(parentName: string, childName: string, isVisible: boolean = true) { @@ -216,11 +208,10 @@ export class MediaUiHelper extends UiBaseLocators { } async clickCaretButtonForMediaName(name: string) { - await this.mediaTreeItem.filter({hasText: name}).last().locator('#caret-button').last().click(); + await this.click(this.mediaTreeItem.filter({hasText: name}).last().locator('#caret-button').last()); } async goToMediaWithName(mediaName: string) { - await expect(this.mediaTreeItem.getByText(mediaName, {exact: true})).toBeVisible(); - await this.mediaTreeItem.getByText(mediaName, {exact: true}).click(); + await this.click(this.mediaTreeItem.getByText(mediaName, {exact: true})); } } \ No newline at end of file diff --git a/lib/helpers/MemberGroupUiHelper.ts b/lib/helpers/MemberGroupUiHelper.ts index 1feb80b1..a557471c 100644 --- a/lib/helpers/MemberGroupUiHelper.ts +++ b/lib/helpers/MemberGroupUiHelper.ts @@ -25,45 +25,42 @@ export class MemberGroupUiHelper extends UiBaseLocators { } async clickMemberGroupsTab() { - await expect(this.memberGroupsTab).toBeVisible(); - await this.page.waitForTimeout(500); - await this.memberGroupsTab.click(); - await expect(this.activeMemberGroupsTab).toBeVisible(); + await this.waitForVisible(this.memberGroupsTab); + await this.page.waitForTimeout(ConstantHelper.wait.short); + await this.click(this.memberGroupsTab); + await this.waitForVisible(this.activeMemberGroupsTab); } async clickMemberGroupCreateButton() { - await this.createMemberGroupBtn.click(); + await this.click(this.createMemberGroupBtn); } async clickMemberGroupsSidebarButton() { - await expect(this.memberGroupsSidebarBtn).toBeVisible(); - await this.memberGroupsSidebarBtn.click(); + await this.click(this.memberGroupsSidebarBtn); } async enterMemberGroupName(name: string) { - await expect(this.memberGroupNameTxt).toBeVisible(); - await this.memberGroupNameTxt.clear(); - await this.memberGroupNameTxt.fill(name); + await this.enterText(this.memberGroupNameTxt, name); } async clickMemberGroupLinkByName(memberGroupName: string) { - await this.page.getByRole('link', {name: memberGroupName}).click(); + await this.click(this.page.getByRole('link', {name: memberGroupName})); } async isMemberGroupNameVisible(memberGroupName: string, isVisible: boolean = true) { - return expect(this.memberGroupView.filter({hasText: memberGroupName})).toBeVisible({visible: isVisible, timeout: 500}); + return expect(this.memberGroupView.filter({hasText: memberGroupName})).toBeVisible({visible: isVisible, timeout: ConstantHelper.wait.short}); } async clickMemberGroupsMenu() { - await this.memberGroupsMenu.click(); + await this.click(this.memberGroupsMenu); } async waitForMemberGroupToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForMemberGroupToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async goToMemberGroups() { diff --git a/lib/helpers/MemberTypeUiHelper.ts b/lib/helpers/MemberTypeUiHelper.ts index dc18ac18..f73c2648 100644 --- a/lib/helpers/MemberTypeUiHelper.ts +++ b/lib/helpers/MemberTypeUiHelper.ts @@ -25,12 +25,11 @@ export class MemberTypeUiHelper extends UiBaseLocators { async goToMemberType(memberTypeName: string) { await this.clickRootFolderCaretButton(); - await this.page.getByLabel(memberTypeName).click(); + await this.click(this.page.getByLabel(memberTypeName)); } async enterMemberTypeName(name: string) { - await this.memberTypeNameTxt.clear(); - await this.memberTypeNameTxt.fill(name); + await this.enterText(this.memberTypeNameTxt, name); } async enterDescriptionForPropertyEditorWithName(propertyEditorName: string, description: string) { diff --git a/lib/helpers/MemberUiHelper.ts b/lib/helpers/MemberUiHelper.ts index d3725dfc..bc71d908 100644 --- a/lib/helpers/MemberUiHelper.ts +++ b/lib/helpers/MemberUiHelper.ts @@ -49,75 +49,60 @@ export class MemberUiHelper extends UiBaseLocators { } async clickMembersTab() { - await this.membersTab.click(); + await this.click(this.membersTab); } async clickDetailsTab() { - await expect(this.detailsTab).toBeVisible(); - await this.detailsTab.click(); + await this.click(this.detailsTab); } async clickMemberLinkByName(memberName: string) { - await this.page.getByRole('link', {name: memberName}).click(); + await this.click(this.page.getByRole('link', {name: memberName})); } async isMemberWithNameVisible(memberName: string, isVisible: boolean = true) { await expect(this.memberTableCollectionRow.getByText(memberName, {exact: true})).toBeVisible({visible: isVisible}); } - + async clickMembersSidebarButton() { - await expect(this.membersSidebarBtn).toBeVisible(); - await this.membersSidebarBtn.click(); + await this.click(this.membersSidebarBtn); } - + async enterSearchKeyword(keyword: string) { - await expect(this.searchTxt).toBeVisible(); - await this.searchTxt.clear(); - await this.searchTxt.fill(keyword); + await this.enterText(this.searchTxt, keyword); } async enterMemberName(name: string) { - await expect(this.memberNameTxt).toBeVisible(); - await this.memberNameTxt.clear(); - await this.memberNameTxt.fill(name); + await this.enterText(this.memberNameTxt, name); } async enterComments(comment: string) { - await expect(this.commentsTxt).toBeVisible(); - await this.commentsTxt.clear(); - await this.commentsTxt.fill(comment); + await this.enterText(this.commentsTxt, comment); } async enterUsername(username: string) { - await expect(this.usernameTxt).toBeVisible(); - await this.usernameTxt.clear(); - await this.usernameTxt.fill(username); + await this.enterText(this.usernameTxt, username); } async enterEmail(email: string) { - await expect(this.emailTxt).toBeVisible(); - await this.emailTxt.clear(); - await this.emailTxt.fill(email); + await this.enterText(this.emailTxt, email); } async enterPassword(password: string) { - await this.passwordTxt.clear(); - await this.passwordTxt.fill(password); + await this.enterText(this.passwordTxt, password); } async enterConfirmPassword(password: string) { - await this.confirmPasswordTxt.clear(); - await this.confirmPasswordTxt.fill(password); + await this.enterText(this.confirmPasswordTxt, password); } async enterConfirmNewPassword(password: string) { - await this.confirmNewPasswordTxt.clear(); - await this.confirmNewPasswordTxt.fill(password); + await this.enterText(this.confirmNewPasswordTxt, password); } async chooseMemberGroup(memberGroupName: string) { await this.clickChooseButton(); - await this.page.getByText(memberGroupName, {exact: true}).click(); + await this.click(this.page.getByText(memberGroupName, {exact: true})); await this.clickChooseContainerButton(); } @@ -126,40 +111,39 @@ export class MemberUiHelper extends UiBaseLocators { } async clickApprovedToggle() { - await this.approvedToggle.click(); + await this.click(this.approvedToggle); } async clickLockedOutToggle() { - await this.lockedOutToggle.click(); + await this.click(this.lockedOutToggle); } async clickTwoFactorAuthenticationToggle() { - await this.twoFactorAuthenticationToggle.click(); + await this.click(this.twoFactorAuthenticationToggle); } async clickChangePasswordButton() { - await this.changePasswordBtn.click(); + await this.click(this.changePasswordBtn); } async clickRemoveMemberGroupByName(memberGroupName: string) { - await this.page.locator('[name="' + memberGroupName + '"]').getByLabel('Remove').click(); + await this.click(this.page.locator(`[name="${memberGroupName}"]`).getByLabel('Remove')); } async enterNewPassword(password: string) { - await this.newPasswordTxt.clear(); - await this.newPasswordTxt.fill(password); + await this.enterText(this.newPasswordTxt, password); } async clickMembersMenu() { - await this.membersMenu.click(); + await this.click(this.membersMenu); } - + async waitForMemberToBeCreated(){ - await this.page.waitForLoadState(); + await this.waitForLoadState(); } - + async waitForMemberToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async goToMembers() { @@ -168,12 +152,10 @@ export class MemberUiHelper extends UiBaseLocators { } async clickInfoTab() { - await expect(this.infoTab).toBeVisible(); - await this.infoTab.click(); + await this.click(this.infoTab); } async clickCreateMembersButton() { - await expect(this.membersCreateBtn).toBeVisible(); - await this.membersCreateBtn.click(); + await this.click(this.membersCreateBtn); } } diff --git a/lib/helpers/ModelsBuilderUiHelper.ts b/lib/helpers/ModelsBuilderUiHelper.ts index 8a4919dd..a762288b 100644 --- a/lib/helpers/ModelsBuilderUiHelper.ts +++ b/lib/helpers/ModelsBuilderUiHelper.ts @@ -1,4 +1,4 @@ -import {Page, Locator, expect} from "@playwright/test"; +import {Page, Locator} from "@playwright/test"; import {UiBaseLocators} from "./UiBaseLocators"; export class ModelsBuilderUiHelper extends UiBaseLocators { @@ -12,10 +12,10 @@ export class ModelsBuilderUiHelper extends UiBaseLocators { } async clickModelsBuilderTab() { - await this.modelsBuilderTab.click(); + await this.click(this.modelsBuilderTab); } async doesModelsBuilderDashboardHaveText(text: string) { - return await expect(this.modelsBuilderDashboardContent).toContainText(text, {timeout: 10000}); + await this.containsText(this.modelsBuilderDashboardContent, text, 10000); } } diff --git a/lib/helpers/PackageUiHelper.ts b/lib/helpers/PackageUiHelper.ts index f09add38..b126a93c 100644 --- a/lib/helpers/PackageUiHelper.ts +++ b/lib/helpers/PackageUiHelper.ts @@ -1,6 +1,7 @@ import {expect, Locator, Page,} from "@playwright/test" import {UiBaseLocators} from "./UiBaseLocators"; import {umbracoConfig} from "../../umbraco.config"; +import {ConstantHelper} from "./ConstantHelper"; export class PackageUiHelper extends UiBaseLocators { private readonly createdTabBtn: Locator; @@ -56,42 +57,38 @@ export class PackageUiHelper extends UiBaseLocators { } async isUmbracoBackofficePackageVisible(isVisible = true) { - return await expect(this.umbracoBackofficePackage).toBeVisible({visible: isVisible}); + await this.isVisible(this.umbracoBackofficePackage, isVisible); } async clickCreatedTab() { - await this.page.waitForTimeout(500); - await expect(this.createdTabBtn).toBeVisible(); - await this.createdTabBtn.click(); - await this.page.waitForTimeout(500); + await this.page.waitForTimeout(ConstantHelper.wait.short); + await this.click(this.createdTabBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickInstalledTab() { - await expect(this.installedTabBtn).toBeVisible(); - await this.installedTabBtn.click(); + await this.click(this.installedTabBtn); } async clickPackagesTab() { - await expect(this.packagesTabBtn).toBeVisible(); - await this.packagesTabBtn.click(); + await this.click(this.packagesTabBtn); } async clickChooseBtn() { - await this.chooseModalBtn.click(); + await this.click(this.chooseModalBtn); } async isMarketPlaceIFrameVisible(isVisible = true) { - return await expect(this.marketPlaceIFrame).toBeVisible({visible: isVisible}); + await this.isVisible(this.marketPlaceIFrame, isVisible); } async clickCreatePackageButton() { - await this.createPackageBtn.click(); + await this.click(this.createPackageBtn); } async enterPackageName(packageName: string) { - await this.packageNameTxt.clear(); - await this.packageNameTxt.fill(packageName); - await this.page.waitForTimeout(500); + await this.enterText(this.packageNameTxt, packageName); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async isPackageNameVisible(packageName: string, isVisible = true) { @@ -99,69 +96,67 @@ export class PackageUiHelper extends UiBaseLocators { } async clickExistingPackageName(packageName: string) { - await this.page.getByRole('button', {name: packageName}).click(); - await this.page.waitForTimeout(500); + await this.click(this.page.getByRole('button', {name: packageName})); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickDeleteButtonForPackageName(packageName: string) { const deletePackageWithNameLocator = this.page.locator('uui-ref-node-package', {hasText: packageName}).getByLabel('Delete'); - await expect(deletePackageWithNameLocator).toBeVisible(); - await deletePackageWithNameLocator.click(); + await this.click(deletePackageWithNameLocator); } async clickSaveChangesToPackageButton() { - await this.saveChangesToPackageBtn.click(); + await this.click(this.saveChangesToPackageBtn); } async clickAddContentToPackageButton() { - await this.addContentToPackageBtn.click(); + await this.click(this.addContentToPackageBtn); } async clickAddMediaToPackageButton() { - await expect(this.addMediaToPackageBtn).toBeVisible(); - await this.addMediaToPackageBtn.click(); + await this.click(this.addMediaToPackageBtn); } async clickAddDocumentTypeToPackageButton() { - await this.addDocumentTypeToPackageBtn.click(); + await this.click(this.addDocumentTypeToPackageBtn); } async clickAddMediaTypeToPackageButton() { - await this.addMediaTypeToPackageBtn.click(); + await this.click(this.addMediaTypeToPackageBtn); } async clickAddLanguageToPackageButton() { - await this.addLanguageToPackageBtn.click(); + await this.click(this.addLanguageToPackageBtn); } async clickAddDictionaryToPackageButton() { - await this.addDictionaryToPackageBtn.click(); + await this.click(this.addDictionaryToPackageBtn); } async clickAddDataTypesToPackageButton() { - await this.addDataTypesToPackageBtn.click(); + await this.click(this.addDataTypesToPackageBtn); } async clickAddTemplatesToPackageButton() { - await this.addTemplatesToPackagesBtn.click(); + await this.click(this.addTemplatesToPackagesBtn); } async clickAddPartialViewToPackageButton() { - await this.addPartialViewToPackageBtn.click(); + await this.click(this.addPartialViewToPackageBtn); } async clickAddScriptToPackageButton() { - await this.addScriptToPackageBtn.click(); + await this.click(this.addScriptToPackageBtn); } async clickAddStylesheetToPackageButton() { - await this.addStylesheetToPackageBtn.click(); + await this.click(this.addStylesheetToPackageBtn); } // Downloads the package and converts it to a string async downloadPackage(packageId: string) { - const responsePromise = this.page.waitForResponse(umbracoConfig.environment.baseUrl + '/umbraco/management/api/v1/package/created/' + packageId + '/download'); - await this.downloadPackageBtn.click(); + const responsePromise = this.page.waitForResponse(`${umbracoConfig.environment.baseUrl}/umbraco/management/api/v1/package/created/${packageId}/download`); + await this.click(this.downloadPackageBtn); const response = await responsePromise; const body = await response.body(); return body.toString().trim(); diff --git a/lib/helpers/PartialViewUiHelper.ts b/lib/helpers/PartialViewUiHelper.ts index fbd115b3..f6c55de7 100644 --- a/lib/helpers/PartialViewUiHelper.ts +++ b/lib/helpers/PartialViewUiHelper.ts @@ -1,5 +1,6 @@ import {Page, Locator, expect} from "@playwright/test" import {UiBaseLocators} from "./UiBaseLocators"; +import {ConstantHelper} from "./ConstantHelper"; export class PartialViewUiHelper extends UiBaseLocators { private readonly newEmptyPartialViewBtn: Locator; @@ -32,31 +33,28 @@ export class PartialViewUiHelper extends UiBaseLocators { } async waitForPartialViewToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForPartialViewToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForPartialViewToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async clickNewEmptyPartialViewButton() { - await this.newEmptyPartialViewBtn.click(); + await this.click(this.newEmptyPartialViewBtn); } async clickNewPartialViewFromSnippetButton() { - await this.newPartialViewFromSnippetBtn.click(); + await this.click(this.newPartialViewFromSnippetBtn); } async enterPartialViewName(partialViewName: string) { - await expect(this.enterAName).toBeVisible(); - await this.enterAName.click(); - await this.enterAName.clear(); - await this.enterAName.fill(partialViewName); - await expect(this.enterAName).toHaveValue(partialViewName); + await this.enterText(this.enterAName, partialViewName); + await this.hasValue(this.enterAName, partialViewName); } async enterPartialViewContent(partialViewContent: string) { @@ -64,18 +62,18 @@ export class PartialViewUiHelper extends UiBaseLocators { await this.waitUntilPartialViewLoaderIsNoLongerVisible(); await this.enterMonacoEditorValue(partialViewContent); // We need this wait, to be sure that the partial view content is loaded. - await this.page.waitForTimeout(200); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async openPartialViewAtRoot(partialViewName: string) { await this.reloadPartialViewTree(); - await this.page.locator('uui-menu-item[label="' + partialViewName +'"]').click(); - await expect(this.enterAName).toBeVisible(); + await this.click(this.page.locator(`uui-menu-item[label="${partialViewName}"]`)); + await this.waitForVisible(this.enterAName); } async createPartialViewFolder(folderName: string) { await this.clickCreateOptionsActionMenuOption(); - await this.newFolderThreeDots.click(); + await this.click(this.newFolderThreeDots); await this.enterFolderName(folderName); await this.clickConfirmCreateFolderButton(); } @@ -85,7 +83,7 @@ export class PartialViewUiHelper extends UiBaseLocators { } async waitUntilPartialViewLoaderIsNoLongerVisible() { - await expect(this.partialViewUiLoader).toBeVisible({visible: false}); + await this.isVisible(this.partialViewUiLoader, false); } async isPartialViewRootTreeItemVisible(partialView: string, isVisible: boolean = true, toReload: boolean = true) { diff --git a/lib/helpers/ProfilingUiHelper.ts b/lib/helpers/ProfilingUiHelper.ts index fb1dd617..f0a91b4f 100644 --- a/lib/helpers/ProfilingUiHelper.ts +++ b/lib/helpers/ProfilingUiHelper.ts @@ -10,17 +10,15 @@ export class ProfilingUiHelper extends UiBaseLocators { super(page); this.profilingTab = page.getByRole('tab', {name: 'Profiling'}); this.activateProfilerByDefaultToggle = page.locator("[label='Activate the profiler by default'] #toggle"); - this.activateProfilerByDefaultCheckbox = page.getByLabel('Activate the profiler by default'); + this.activateProfilerByDefaultCheckbox = page.locator("[label='Activate the profiler by default'] input[type='checkbox']"); } async clickProfilingTab() { - await expect(this.profilingTab).toBeVisible(); - await this.profilingTab.click(); + await this.click(this.profilingTab); } async clickActivateProfilerByDefaultToggle() { - await expect(this.activateProfilerByDefaultToggle).toBeVisible(); - await this.activateProfilerByDefaultToggle.click(); + await this.click(this.activateProfilerByDefaultToggle); } async isActivateProfilerByDefaultToggleChecked(isChecked: boolean) { diff --git a/lib/helpers/PublishedStatusUiHelper.ts b/lib/helpers/PublishedStatusUiHelper.ts index 80a68f71..c493f639 100644 --- a/lib/helpers/PublishedStatusUiHelper.ts +++ b/lib/helpers/PublishedStatusUiHelper.ts @@ -22,27 +22,27 @@ export class PublishedStatusUiHelper extends UiBaseLocators { } async clickPublishedStatusTab() { - await this.publishedStatusTab.click(); + await this.click(this.publishedStatusTab); } async clickRefreshStatusButton() { - await this.refreshStatusBtn.click(); + await this.click(this.refreshStatusBtn); } async clickReloadMemoryCacheButton() { - await this.reloadMemoryCacheBtn.click(); + await this.click(this.reloadMemoryCacheBtn); } async clickRebuildDatabaseCacheButton() { - await this.rebuildDatabaseCacheBtn.click(); + await this.click(this.rebuildDatabaseCacheBtn); } async clickSnapshotInternalCacheButton() { - await this.snapshotInternalCacheBtn.click(); + await this.click(this.snapshotInternalCacheBtn); } async clickContinueButton() { - await this.continueBtn.click(); + await this.click(this.continueBtn); } async isPublishedCacheStatusVisible(status: string) { diff --git a/lib/helpers/RedirectManagementUiHelper.ts b/lib/helpers/RedirectManagementUiHelper.ts index 42ab226f..f2ca5d8d 100644 --- a/lib/helpers/RedirectManagementUiHelper.ts +++ b/lib/helpers/RedirectManagementUiHelper.ts @@ -1,4 +1,4 @@ -import {Page, Locator, expect} from "@playwright/test"; +import {Page, Locator} from "@playwright/test"; import {UiBaseLocators} from "./UiBaseLocators"; export class RedirectManagementUiHelper extends UiBaseLocators { @@ -22,35 +22,31 @@ export class RedirectManagementUiHelper extends UiBaseLocators { } async clickRedirectManagementTab() { - await expect(this.redirectManagementTab).toBeVisible(); - await this.redirectManagementTab.click(); + await this.click(this.redirectManagementTab); } async clickEnableURLTrackerButton() { - await this.enableURLTrackerBtn.click(); + await this.click(this.enableURLTrackerBtn); } async clickDisableURLTrackerButton() { - await this.disableURLTrackerBtn.click(); + await this.click(this.disableURLTrackerBtn); } async enterOriginalUrl(url: string) { - await this.originalUrlTxt.clear(); - await this.originalUrlTxt.fill(url); + await this.enterText(this.originalUrlTxt, url); } async clickSearchButton() { - await expect(this.searchBtn).toBeVisible(); - await this.searchBtn.click(); + await this.click(this.searchBtn); } async deleteFirstRedirectURL() { - await expect(this.firstDeleteButton).toBeVisible(); - await this.firstDeleteButton.click(); + await this.click(this.firstDeleteButton); await this.clickConfirmToDeleteButton(); } async doesRedirectManagementRowsHaveCount(itemCount: number) { - await expect(this.redirectManagementRows).toHaveCount(itemCount); + await this.hasCount(this.redirectManagementRows, itemCount); } } diff --git a/lib/helpers/RelationTypeUiHelper.ts b/lib/helpers/RelationTypeUiHelper.ts index fe7de7c7..0974d2ba 100644 --- a/lib/helpers/RelationTypeUiHelper.ts +++ b/lib/helpers/RelationTypeUiHelper.ts @@ -38,8 +38,7 @@ export class RelationTypeUiHelper extends UiBaseLocators{ } async goToRelationTypeWithName(name: string) { - await expect(this.relationTypeCollection.getByText(name)).toBeVisible(); - await this.relationTypeCollection.getByText(name).click(); + await this.click(this.relationTypeCollection.getByText(name)); await this.waitUntilUiLoaderIsNoLongerVisible(); } @@ -53,32 +52,31 @@ export class RelationTypeUiHelper extends UiBaseLocators{ async openRelationTypeByNameAtRoot(relationTypeName: string) { await this.clickRootFolderCaretButton(); - await this.page.getByLabel(relationTypeName).click(); + await this.click(this.page.getByLabel(relationTypeName)); } async enterRelationTypeName(name: string) { - await this.relationTypeNameTxt.clear(); - await this.relationTypeNameTxt.fill(name); + await this.enterText(this.relationTypeNameTxt, name); } async clickParentToChildRadioButton() { - await this.parentToChildRadioBtn.click(); + await this.click(this.parentToChildRadioBtn); } async doesParentTypeContainValue(value: string) { - await expect(this.relationTypeParentType).toContainText(value); + await this.containsText(this.relationTypeParentType, value); } async doesChildTypeContainValue(value: string) { - await expect(this.relationTypeChildType).toContainText(value); + await this.containsText(this.relationTypeChildType, value); } async doesBidirectionalContainValue(value: string) { - await expect(this.relationTypeBidirectional).toContainText(value); + await this.containsText(this.relationTypeBidirectional, value); } async doesDependencyContainValue(value: string) { - await expect(this.relationTypeDependency).toContainText(value); + await this.containsText(this.relationTypeDependency, value); } async isRelationWithParentAndChildVisible(parent: string, child: string, isVisible: boolean = true) { @@ -86,18 +84,18 @@ export class RelationTypeUiHelper extends UiBaseLocators{ } async clickBidirectionalRadioButton() { - await this.bidirectionalRadioBtn.click(); + await this.click(this.bidirectionalRadioBtn); } async clickIsDependencyToggle() { - await this.isDependencyToggle.click(); + await this.click(this.isDependencyToggle); } async selectParentOption(option: string) { - await this.parentDropDownBox.selectOption({ label: option }); + await this.selectByText(this.parentDropDownBox, option); } async selectChildOption(option: string) { - await this.childDropDownBox.selectOption({ label: option }); + await this.selectByText(this.childDropDownBox, option); } } \ No newline at end of file diff --git a/lib/helpers/ScriptUiHelper.ts b/lib/helpers/ScriptUiHelper.ts index 425f9233..a3494f7b 100644 --- a/lib/helpers/ScriptUiHelper.ts +++ b/lib/helpers/ScriptUiHelper.ts @@ -22,8 +22,7 @@ export class ScriptUiHelper extends UiBaseLocators{ async createScriptFolder(folderName: string) { await this.clickCreateOptionsActionMenuOption(); - await expect(this.newFolderThreeDots).toBeVisible(); - await this.newFolderThreeDots.click(); + await this.click(this.newFolderThreeDots); await this.enterFolderName(folderName); await this.clickConfirmCreateFolderButton(); } @@ -37,32 +36,30 @@ export class ScriptUiHelper extends UiBaseLocators{ } async clickNewJavascriptFileButton() { - await expect(this.newJavascriptFileBtn).toBeVisible(); - await this.newJavascriptFileBtn.click(); + await this.click(this.newJavascriptFileBtn); } async waitForScriptToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForScriptToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForScriptToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } // Will only work for root scripts async goToScript(scriptName: string) { await this.goToSection(ConstantHelper.sections.settings); await this.reloadScriptTree(); - await this.page.getByLabel(scriptName, {exact: true}).click(); + await this.click(this.page.getByLabel(scriptName, {exact: true})); } async enterScriptName(scriptContent: string) { - await expect(this.enterAName).toBeVisible(); - await this.enterAName.fill(scriptContent); + await this.enterText(this.enterAName, scriptContent); } async enterScriptContent(scriptContent: string) { @@ -71,7 +68,7 @@ export class ScriptUiHelper extends UiBaseLocators{ async openScriptAtRoot(scriptName: string) { await this.reloadScriptTree(); - await this.page.getByLabel(scriptName, {exact: true}).click(); + await this.click(this.page.getByLabel(scriptName, {exact: true})); } async reloadScriptTree() { diff --git a/lib/helpers/StylesheetUiHelper.ts b/lib/helpers/StylesheetUiHelper.ts index 188f6cd0..e214acb6 100644 --- a/lib/helpers/StylesheetUiHelper.ts +++ b/lib/helpers/StylesheetUiHelper.ts @@ -38,31 +38,27 @@ export class StylesheetUiHelper extends UiBaseLocators{ } async clickNewStylesheetButton() { - await expect(this.newStylesheetBtn).toBeVisible(); - await this.newStylesheetBtn.click(); - } - + await this.click(this.newStylesheetBtn); + } + async clickNewStylesheetFolderButton() { - await expect(this.newStylesheetFolderBtn).toBeVisible(); - await this.newStylesheetFolderBtn.click(); + await this.click(this.newStylesheetFolderBtn); } async waitForStylesheetToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForStylesheetToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForStylesheetToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async enterStylesheetName(stylesheetName: string) { - await expect(this.stylesheetNameTxt).toBeVisible(); - await this.stylesheetNameTxt.clear(); - await this.stylesheetNameTxt.fill(stylesheetName); + await this.enterText(this.stylesheetNameTxt, stylesheetName); } async enterStylesheetContent(stylesheetContent: string) { @@ -71,7 +67,7 @@ export class StylesheetUiHelper extends UiBaseLocators{ async openStylesheetByNameAtRoot(stylesheetName: string) { await this.reloadStylesheetTree(); - await this.page.getByLabel(stylesheetName, {exact: true}).click(); + await this.click(this.page.getByLabel(stylesheetName, {exact: true})); } async reloadStylesheetTree() { @@ -88,6 +84,6 @@ export class StylesheetUiHelper extends UiBaseLocators{ async goToStylesheet(stylesheetName: string) { await this.goToSection(ConstantHelper.sections.settings); await this.reloadStylesheetTree(); - await this.page.getByLabel(stylesheetName, {exact: true}).click(); + await this.click(this.page.getByLabel(stylesheetName, {exact: true})); } } \ No newline at end of file diff --git a/lib/helpers/TelemetryDataUiHelper.ts b/lib/helpers/TelemetryDataUiHelper.ts index 1a47b178..1f7a7c8d 100644 --- a/lib/helpers/TelemetryDataUiHelper.ts +++ b/lib/helpers/TelemetryDataUiHelper.ts @@ -1,4 +1,4 @@ -import {Page, Locator, expect} from "@playwright/test"; +import {Page, Locator} from "@playwright/test"; import {UiBaseLocators} from "./UiBaseLocators"; export class TelemetryDataUiHelper extends UiBaseLocators { @@ -12,7 +12,7 @@ export class TelemetryDataUiHelper extends UiBaseLocators { } async clickTelemetryDataTab() { - await this.telemetryDataTab.click(); + await this.click(this.telemetryDataTab); } async changeTelemetryDataLevelValue(value: string) { @@ -20,6 +20,6 @@ export class TelemetryDataUiHelper extends UiBaseLocators { } async doesTelemetryDataLevelHaveValue(value: string) { - return await expect(this.telemetryDataLevelToggle).toHaveValue(value); + await this.hasValue(this.telemetryDataLevelToggle, value); } } diff --git a/lib/helpers/TemplateUiHelper.ts b/lib/helpers/TemplateUiHelper.ts index 3b6cdd61..cc936a6d 100644 --- a/lib/helpers/TemplateUiHelper.ts +++ b/lib/helpers/TemplateUiHelper.ts @@ -31,68 +31,63 @@ export class TemplateUiHelper extends UiBaseLocators { } async waitForTemplateToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForTemplateToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForTemplateToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async goToTemplate(templateName: string, childTemplateName: string = '') { await this.goToSection(ConstantHelper.sections.settings); await this.reloadTemplateTree(); if (childTemplateName === '') { - await this.page.getByLabel(templateName, {exact: true}).click(); - await expect(this.enterAName).toHaveValue(templateName); + await this.click(this.page.getByLabel(templateName, {exact: true})); + await this.hasValue(this.enterAName, templateName); } else { await this.openCaretButtonForName(templateName); - await this.page.getByLabel(childTemplateName , {exact: true}).click(); - await expect(this.enterAName).toHaveValue(childTemplateName); + await this.click(this.page.getByLabel(childTemplateName, {exact: true})); + await this.hasValue(this.enterAName, childTemplateName); } - await this.page.waitForTimeout(1000); + await this.page.waitForTimeout(ConstantHelper.wait.medium); } async clickSectionsButton() { - await expect(this.sectionsBtn).toBeVisible(); - await this.sectionsBtn.click(); + await this.click(this.sectionsBtn); } async clickChangeMasterTemplateButton() { - await expect(this.changeMasterTemplateBtn).toBeVisible(); - await this.changeMasterTemplateBtn.click(); + await this.click(this.changeMasterTemplateBtn); } async enterTemplateName(templateName: string) { - await expect(this.enterAName).toBeVisible(); - await this.enterAName.clear(); - await this.enterAName.fill(templateName); + await this.enterText(this.enterAName, templateName); } async enterTemplateContent(templateContent: string) { // We need this wait, to be sure that the template content is loaded. - await this.page.waitForTimeout(200); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); await this.enterMonacoEditorValue(templateContent); } async isMasterTemplateNameVisible(templateName: string, isVisible: boolean = true) { - await expect(this.page.getByLabel('Master template: ' + templateName)).toBeVisible({visible: isVisible}); + await expect(this.page.getByLabel(`Master template: ${templateName}`)).toBeVisible({visible: isVisible}); } async clickRemoveMasterTemplateButton() { - await expect(this.removeMasterTemplateBtn).toBeVisible(); - await this.removeMasterTemplateBtn.click(); + await this.click(this.removeMasterTemplateBtn); } async insertSection(sectionType: string, sectionName: string = '') { await this.clickSectionsButton(); - await expect(this.submitBtn).toBeVisible(); - await this.page.locator('[label="' + sectionType + '"]').click(); + await this.waitForVisible(this.submitBtn); + await this.click(this.page.locator(`[label="${sectionType}"]`)); if (sectionName !== '') { - await expect(this.sectionNameTxt).toBeVisible(); + await this.waitForVisible(this.sectionNameTxt); await this.sectionNameTxt.fill(sectionName); } await this.clickSubmitButton(); diff --git a/lib/helpers/UiBaseLocators.ts b/lib/helpers/UiBaseLocators.ts index 2dc71b7c..149c318e 100644 --- a/lib/helpers/UiBaseLocators.ts +++ b/lib/helpers/UiBaseLocators.ts @@ -1,1342 +1,1374 @@ import {expect, Locator, Page} from "@playwright/test" import {ConstantHelper} from "./ConstantHelper"; +import {BasePage} from "./BasePage"; -export class UiBaseLocators { - public readonly page: Page; +export class UiBaseLocators extends BasePage { + // Core Action Buttons public readonly saveBtn: Locator; - public readonly chooseBtn: Locator; public readonly submitBtn: Locator; - public readonly createFolderBtn: Locator; - public readonly breadcrumbBtn: Locator; - public readonly confirmToDeleteBtn: Locator; + public readonly confirmBtn: Locator; + public readonly chooseBtn: Locator; + public readonly chooseModalBtn: Locator; + public readonly createBtn: Locator; + public readonly addBtn: Locator; + public readonly updateBtn: Locator; + public readonly changeBtn: Locator; + public readonly deleteBtn: Locator; public readonly deleteExactBtn: Locator; - public readonly confirmCreateFolderBtn: Locator; + public readonly removeExactBtn: Locator; public readonly insertBtn: Locator; - public readonly modalCaretBtn: Locator; - public readonly queryBuilderBtn: Locator; - public readonly queryBuilderOrderedBy: Locator; - public readonly queryBuilderCreateDate: Locator; + public readonly renameBtn: Locator; + public readonly reloadBtn: Locator; + public readonly reloadChildrenBtn: Locator; + public readonly restoreBtn: Locator; + public readonly disableBtn: Locator; + public readonly enableBtn: Locator; + public readonly actionBtn: Locator; + public readonly nextBtn: Locator; + + // Confirmation Buttons + public readonly confirmToDeleteBtn: Locator; + public readonly confirmCreateFolderBtn: Locator; + public readonly confirmToRemoveBtn: Locator; + public readonly confirmToSubmitBtn: Locator; + public readonly confirmDisableBtn: Locator; + public readonly confirmEnableBtn: Locator; + public readonly confirmRenameBtn: Locator; + public readonly confirmTrashBtn: Locator; + + // Folder Management + public readonly createFolderBtn: Locator; public readonly folderNameTxt: Locator; - public readonly textAreaInputArea: Locator; - public readonly wherePropertyAliasBtn: Locator; - public readonly whereOperatorBtn: Locator; - public readonly whereConstrainValueTxt: Locator; - public readonly orderByPropertyAliasBtn: Locator; - public readonly ascendingBtn: Locator; - public readonly queryBuilderShowCode: Locator; - public readonly createThreeDotsBtn: Locator; + public readonly folderBtn: Locator; public readonly newFolderThreeDotsBtn: Locator; - public readonly renameThreeDotsBtn: Locator; - public readonly newNameTxt: Locator; - public readonly renameModalBtn: Locator; - public readonly createBtn: Locator; - public readonly successState: Locator; - public readonly chooseModalBtn: Locator; - public readonly addBtn: Locator; public readonly renameFolderThreeDotsBtn: Locator; public readonly renameFolderBtn: Locator; public readonly updateFolderBtn: Locator; - public readonly filterChooseBtn: Locator; - public readonly updateBtn: Locator; - public readonly changeBtn: Locator; + public readonly deleteFolderThreeDotsBtn: Locator; + + // Navigation & Menu + public readonly breadcrumbBtn: Locator; + public readonly leftArrowBtn: Locator; + public readonly caretBtn: Locator; + public readonly modalCaretBtn: Locator; + public readonly backOfficeHeader: Locator; + public readonly backOfficeMain: Locator; + public readonly sectionLinks: Locator; + public readonly sectionSidebar: Locator; + public readonly menuItem: Locator; + public readonly actionsMenuContainer: Locator; + public readonly treeItem: Locator; + + // Three Dots Menu Buttons + public readonly createThreeDotsBtn: Locator; + public readonly renameThreeDotsBtn: Locator; + public readonly deleteThreeDotsBtn: Locator; + + // Modal & Container + public readonly sidebarModal: Locator; + public readonly openedModal: Locator; + public readonly container: Locator; + public readonly containerChooseBtn: Locator; + public readonly containerSaveAndPublishBtn: Locator; + public readonly createModalBtn: Locator; + + // Document Type & Property Editor + public readonly documentTypeNode: Locator; public readonly propertyNameTxt: Locator; public readonly selectPropertyEditorBtn: Locator; + public readonly editorSettingsBtn: Locator; + public readonly enterPropertyEditorDescriptionTxt: Locator; + public readonly property: Locator; + public readonly addPropertyBtn: Locator; + public readonly labelAboveBtn: Locator; + + // Group & Tab Management public readonly addGroupBtn: Locator; - public readonly iAmDoneReorderingBtn: Locator; - public readonly reorderBtn: Locator; - public readonly compositionsBtn: Locator; + public readonly groupLabel: Locator; + public readonly typeGroups: Locator; public readonly addTabBtn: Locator; - public readonly descriptionBtn: Locator; - public readonly enterDescriptionTxt: Locator; + public readonly unnamedTabTxt: Locator; + public readonly structureTabBtn: Locator; + + // Validation & Mandatory public readonly mandatoryToggle: Locator; public readonly validation: Locator; public readonly regexTxt: Locator; public readonly regexMessageTxt: Locator; - public readonly structureTabBtn: Locator; + public readonly validationMessage: Locator; + + // Composition & Structure + public readonly compositionsBtn: Locator; public readonly allowAtRootBtn: Locator; - public readonly addPropertyBtn: Locator; - public readonly typeToFilterSearchTxt: Locator; - public readonly editorSettingsBtn: Locator; - public readonly labelAboveBtn: Locator; - public readonly unnamedTabTxt: Locator; - public readonly deleteThreeDotsBtn: Locator; - public readonly removeExactBtn: Locator; - public readonly confirmBtn: Locator; - public readonly disableBtn: Locator; - public readonly confirmDisableBtn: Locator; - public readonly enableBtn: Locator; - public readonly confirmEnableBtn: Locator; - public readonly iconBtn: Locator; - public readonly aliasLockBtn: Locator; - public readonly aliasNameTxt: Locator; - public readonly deleteFolderThreeDotsBtn: Locator; - public readonly createLink: Locator; + public readonly allowedChildNodesModal: Locator; + public readonly addCollectionBtn: Locator; + + // Reorder + public readonly iAmDoneReorderingBtn: Locator; + public readonly reorderBtn: Locator; + + // Query Builder + public readonly queryBuilderBtn: Locator; + public readonly queryBuilderOrderedBy: Locator; + public readonly queryBuilderCreateDate: Locator; + public readonly queryBuilderShowCode: Locator; + public readonly wherePropertyAliasBtn: Locator; + public readonly whereOperatorBtn: Locator; + public readonly whereConstrainValueTxt: Locator; + public readonly orderByPropertyAliasBtn: Locator; + public readonly ascendingBtn: Locator; + public readonly chooseRootContentBtn: Locator; + public readonly returnedItemsCount: Locator; + public readonly queryResults: Locator; + + // Insert & Template public readonly insertValueBtn: Locator; public readonly insertPartialViewBtn: Locator; public readonly insertDictionaryItemBtn: Locator; public readonly chooseFieldDropDown: Locator; public readonly systemFieldsOption: Locator; public readonly chooseFieldValueDropDown: Locator; - public readonly renameBtn: Locator; - public readonly returnedItemsCount: Locator; - public readonly chooseRootContentBtn: Locator; - public readonly queryResults: Locator; - public readonly reloadBtn: Locator; - public readonly confirmToRemoveBtn: Locator; - public readonly confirmToSubmitBtn: Locator; - public readonly typeGroups: Locator; - public readonly allowedChildNodesModal: Locator; - public readonly addCollectionBtn: Locator; - public readonly errorNotification: Locator; - public readonly confirmRenameBtn: Locator; - public readonly successNotification: Locator; - public readonly leftArrowBtn: Locator; - public readonly clickToUploadBtn: Locator; - public readonly backOfficeHeader: Locator; + public readonly breadcrumbsTemplateModal: Locator; + + // Rename + public readonly newNameTxt: Locator; + public readonly renameModalBtn: Locator; + + // State & Notification + public readonly successState: Locator; + public readonly successStateIcon: Locator; public readonly failedStateButton: Locator; - public readonly sidebarModal: Locator; + public readonly successNotification: Locator; + public readonly errorNotification: Locator; + + // Search & Filter + public readonly typeToFilterSearchTxt: Locator; + public readonly filterChooseBtn: Locator; + + // Text Input + public readonly textAreaInputArea: Locator; public readonly enterAName: Locator; - public readonly mediaCardItems: Locator; - public readonly enterPropertyEditorDescriptionTxt: Locator; - public readonly breadcrumbsTemplateModal: Locator; - public readonly containerChooseBtn: Locator; - public readonly documentTypeNode: Locator; - public readonly groupLabel: Locator; - public readonly containerSaveAndPublishBtn: Locator; - public readonly confirmTrashBtn: Locator; + public readonly descriptionBtn: Locator; + public readonly enterDescriptionTxt: Locator; + public readonly aliasLockBtn: Locator; + public readonly aliasNameTxt: Locator; + + // Icon + public readonly iconBtn: Locator; + + // Create Link + public readonly createLink: Locator; + + // Recycle Bin public readonly recycleBinBtn: Locator; - public readonly recycleBinMenuItemCaretBtn: Locator; public readonly recycleBinMenuItem: Locator; + public readonly recycleBinMenuItemCaretBtn: Locator; + + // View Options public readonly gridBtn: Locator; public readonly listBtn: Locator; public readonly viewBundleBtn: Locator; - public readonly chooseDocumentInputBtn: Locator; - public readonly chooseMediaInputBtn: Locator; - public readonly container: Locator; - public readonly createDocumentBlueprintBtn: Locator; - public readonly actionBtn: Locator; + + // Media + public readonly mediaCardItems: Locator; public readonly mediaPickerModalSubmitBtn: Locator; - public readonly deleteBtn: Locator; - public readonly createModalBtn: Locator; public readonly mediaCaptionAltTextModalSubmitBtn: Locator; + public readonly clickToUploadBtn: Locator; + public readonly inputDropzone: Locator; + public readonly imageCropperField: Locator; + public readonly inputUploadField: Locator; + public readonly chooseMediaInputBtn: Locator; + + // Embedded Media public readonly embeddedMediaModal: Locator; public readonly embeddedURLTxt: Locator; public readonly embeddedRetrieveBtn: Locator; public readonly embeddedMediaModalConfirmBtn: Locator; public readonly embeddedPreview: Locator; - public readonly sectionSidebar: Locator; - public readonly actionsMenuContainer: Locator; - public readonly menuItem: Locator; - public readonly property: Locator; + + // Document & Content + public readonly chooseDocumentInputBtn: Locator; + public readonly createDocumentBlueprintBtn: Locator; + public readonly createDocumentBlueprintModal: Locator; + public readonly createNewDocumentBlueprintBtn: Locator; + + // User public readonly currentUserAvatarBtn: Locator; public readonly newPasswordTxt: Locator; public readonly confirmPasswordTxt: Locator; public readonly currentPasswordTxt: Locator; - public readonly createOptionActionListModal: Locator; + + // Collection & Table + public readonly collectionTreeItemTableRow: Locator; public readonly createActionButtonCollection: Locator; public readonly createActionBtn: Locator; - public readonly collectionTreeItemTableRow: Locator; - public readonly folderBtn: Locator; - public readonly reloadChildrenBtn: Locator; + public readonly createOptionActionListModal: Locator; + + // Reference & Entity public readonly confirmActionModalEntityReferences: Locator; public readonly referenceHeadline: Locator; public readonly entityItemRef: Locator; - public readonly validationMessage: Locator; - public readonly successStateIcon: Locator; + public readonly entityItem: Locator; + + // Workspace & Action public readonly workspaceAction: Locator; + public readonly workspaceActionMenuBtn: Locator; public readonly entityAction: Locator; public readonly openEntityAction: Locator; - public readonly caretBtn: Locator; - public readonly workspaceActionMenuBtn: Locator; - public readonly monacoEditor: Locator; - public readonly createNewDocumentBlueprintBtn: Locator; - public readonly openedModal: Locator; - public readonly uiLoader: Locator; - public readonly createDocumentBlueprintModal: Locator; - public readonly inputDropzone: Locator; - public readonly imageCropperField: Locator; - public readonly inputUploadField: Locator; - public readonly entityItem: Locator; - public readonly sectionLinks: Locator; - public readonly restoreBtn: Locator; - public readonly backOfficeMain: Locator; + + // Pagination public readonly firstPaginationBtn: Locator; public readonly nextPaginationBtn: Locator; - public readonly nextBtn: Locator; + + // Editor + public readonly monacoEditor: Locator; + + // Loader + public readonly uiLoader: Locator; constructor(page: Page) { - this.page = page; + super(page); + + // Core Action Buttons this.saveBtn = page.getByLabel('Save', {exact: true}); this.submitBtn = page.getByLabel('Submit'); + this.confirmBtn = page.getByLabel('Confirm'); + this.chooseBtn = page.getByLabel('Choose', {exact: true}); + this.chooseModalBtn = page.locator('uui-modal-sidebar').locator('[look="primary"]').getByLabel('Choose'); + this.createBtn = page.getByRole('button', {name: /^Create(…)?$/}); + this.addBtn = page.getByRole('button', {name: 'Add', exact: true}); + this.updateBtn = page.getByLabel('Update'); + this.changeBtn = page.getByLabel('Change'); + this.deleteBtn = page.getByRole('button', {name: /^Delete(…)?$/}); this.deleteExactBtn = page.getByRole('button', {name: 'Delete', exact: true}); + this.removeExactBtn = page.getByLabel('Remove', {exact: true}); + this.insertBtn = page.locator('uui-box uui-button').filter({hasText: 'Insert'}); + this.renameBtn = page.getByRole('button', {name: /^Rename(…)?$/}); + this.reloadBtn = page.getByRole('button', {name: 'Reload', exact: true}); + this.reloadChildrenBtn = page.getByRole('button', {name: 'Reload children'}); + this.restoreBtn = page.getByLabel('Restore', {exact: true}); + this.disableBtn = page.getByLabel('Disable', {exact: true}); + this.enableBtn = page.getByLabel('Enable'); + this.actionBtn = page.getByTestId('workspace:action-menu-button'); + this.nextBtn = page.getByLabel('Next'); + + // Confirmation Buttons this.confirmToDeleteBtn = page.locator('#confirm').getByLabel('Delete'); this.confirmCreateFolderBtn = page.locator('#confirm').getByLabel('Create Folder'); - this.breadcrumbBtn = page.getByLabel('Breadcrumb'); + this.confirmToRemoveBtn = page.locator('#confirm').getByLabel('Remove'); + this.confirmToSubmitBtn = page.locator('#confirm').getByLabel('Submit'); + this.confirmDisableBtn = page.locator('#confirm').getByLabel('Disable'); + this.confirmEnableBtn = page.locator('#confirm').getByLabel('Enable'); + this.confirmRenameBtn = page.locator('#confirm').getByLabel('Rename'); + this.confirmTrashBtn = page.locator('#confirm').getByLabel('Trash'); + + // Folder Management this.createFolderBtn = page.getByLabel('Create folder'); - this.insertBtn = page.locator('uui-box uui-button').filter({hasText: 'Insert'}); - this.sidebarModal = page.locator('uui-modal-sidebar'); - this.modalCaretBtn = this.sidebarModal.locator('#caret-button'); - this.enterAName = page.getByLabel('Enter a name...', {exact: true}); - this.queryBuilderBtn = page.locator('#query-builder-button'); - this.queryBuilderOrderedBy = page.locator('#property-alias-dropdown').getByLabel('Property alias'); - this.queryBuilderCreateDate = page.locator('#property-alias-dropdown').getByText('CreateDate').locator(".."); this.folderNameTxt = page.getByLabel('Enter a folder name'); - this.textAreaInputArea = page.locator('textarea.ime-text-area'); - this.wherePropertyAliasBtn = page.locator('#property-alias-dropdown'); - this.whereOperatorBtn = page.locator('#operator-dropdown'); - this.whereConstrainValueTxt = page.getByLabel('constrain value'); - this.orderByPropertyAliasBtn = page.locator('#sort-dropdown'); - this.ascendingBtn = page.locator('[key="template_ascending"]'); - this.queryBuilderShowCode = page.locator('umb-code-block'); - this.createThreeDotsBtn = page.getByText('Create…', {exact: true}); - this.chooseBtn = page.getByLabel('Choose', {exact: true}); - this.containerChooseBtn = page.locator('#container').getByLabel('Choose'); - this.containerSaveAndPublishBtn = page.locator('#container').getByLabel('Save and Publish'); + this.folderBtn = page.locator('umb-entity-create-option-action-list-modal').locator('umb-ref-item', {hasText: 'Folder'}); this.newFolderThreeDotsBtn = page.getByLabel('New Folder…'); - this.renameThreeDotsBtn = page.getByLabel('Rename…', {exact: true}); - this.newNameTxt = page.getByRole('textbox', {name: 'Enter new name...'}); - this.renameModalBtn = page.locator('umb-rename-modal').getByLabel('Rename'); - this.createBtn = page.getByRole('button', {name: /^Create(…)?$/}); - this.actionsMenuContainer = page.locator('uui-scroll-container'); - this.successState = page.locator('[state="success"]'); - this.chooseModalBtn = this.sidebarModal.locator('[look="primary"]').getByLabel('Choose'); - this.addBtn = page.getByRole('button', {name: 'Add', exact: true}); - this.renameFolderThreeDotsBtn = page.getByRole('button', {name: 'Rename folder…'}) + this.renameFolderThreeDotsBtn = page.getByRole('button', {name: 'Rename folder…'}); this.renameFolderBtn = page.getByLabel('Rename folder'); - this.confirmRenameBtn = page.locator('#confirm').getByLabel('Rename'); this.updateFolderBtn = page.getByLabel('Update folder'); - this.filterChooseBtn = page.locator('button').filter({hasText: 'Choose'}); - this.updateBtn = page.getByLabel('Update'); - this.changeBtn = page.getByLabel('Change'); + this.deleteFolderThreeDotsBtn = page.locator('#action-modal').getByLabel('Delete Folder...'); + + // Navigation & Menu + this.breadcrumbBtn = page.getByLabel('Breadcrumb'); + this.leftArrowBtn = page.locator('[name="icon-arrow-left"] svg'); + this.caretBtn = page.locator('#caret-button'); + this.modalCaretBtn = page.locator('uui-modal-sidebar').locator('#caret-button'); + this.backOfficeHeader = page.locator('umb-backoffice-header'); + this.backOfficeMain = page.locator('umb-backoffice-main'); + this.sectionLinks = page.getByTestId('section-links'); + this.sectionSidebar = page.locator('umb-section-sidebar'); + this.menuItem = page.locator('uui-menu-item'); + this.actionsMenuContainer = page.locator('uui-scroll-container'); + this.treeItem = page.locator('umb-tree-item'); + + // Three Dots Menu Buttons + this.createThreeDotsBtn = page.getByText('Create…', {exact: true}); + this.renameThreeDotsBtn = page.getByLabel('Rename…', {exact: true}); + this.deleteThreeDotsBtn = page.getByLabel('Delete…'); + + // Modal & Container + this.sidebarModal = page.locator('uui-modal-sidebar'); + this.openedModal = page.locator('uui-modal-container[backdrop]'); + this.container = page.locator('#container'); + this.containerChooseBtn = page.locator('#container').getByLabel('Choose'); + this.containerSaveAndPublishBtn = page.locator('#container').getByLabel('Save and Publish'); + this.createModalBtn = page.locator('uui-modal-sidebar').getByLabel('Create', {exact: true}); + + // Document Type & Property Editor + this.documentTypeNode = page.locator('uui-ref-node-document-type'); this.propertyNameTxt = page.getByTestId('input:entity-name').locator('#input').first(); this.selectPropertyEditorBtn = page.getByLabel('Select Property Editor'); + this.editorSettingsBtn = page.getByLabel('Editor settings'); + this.enterPropertyEditorDescriptionTxt = page.locator('uui-modal-sidebar').getByTestId('input:entity-description').locator('#textarea'); + this.property = page.locator('umb-property'); + this.addPropertyBtn = page.getByLabel('Add property', {exact: true}); + this.labelAboveBtn = page.locator('.appearance-option').filter({hasText: 'Label above'}); + + // Group & Tab Management this.addGroupBtn = page.getByLabel('Add group', {exact: true}); - this.iAmDoneReorderingBtn = page.getByLabel('I am done reordering'); - this.reorderBtn = page.getByLabel('Reorder'); - this.compositionsBtn = page.getByLabel('Compositions'); + this.groupLabel = page.getByLabel('Group', {exact: true}); + this.typeGroups = page.locator('umb-content-type-design-editor-group'); this.addTabBtn = page.getByLabel('Add tab'); - this.descriptionBtn = page.getByLabel('Description'); - this.enterDescriptionTxt = page.getByLabel('Enter a description...'); + this.unnamedTabTxt = page.getByTestId('tab:').getByTestId('tab:name-input').locator('#input'); + this.structureTabBtn = page.locator('uui-tab').filter({hasText: 'Structure'}).locator('svg'); + + // Validation & Mandatory this.mandatoryToggle = page.locator('#mandatory #toggle'); this.validation = page.locator('#native'); this.regexTxt = page.locator('input[name="pattern"]'); this.regexMessageTxt = page.locator('textarea[name="pattern-message"]'); - this.structureTabBtn = page.locator('uui-tab').filter({hasText: 'Structure'}).locator('svg'); + this.validationMessage = page.locator('umb-form-validation-message').locator('#messages'); + + // Composition & Structure + this.compositionsBtn = page.getByLabel('Compositions'); this.allowAtRootBtn = page.locator('label').filter({hasText: 'Allow at root'}); - this.addPropertyBtn = page.getByLabel('Add property', {exact: true}); - this.typeToFilterSearchTxt = page.locator('[type="search"] #input'); - this.editorSettingsBtn = page.getByLabel('Editor settings'); - this.labelAboveBtn = page.locator('.appearance-option').filter({hasText: 'Label above'}); - this.firstPaginationBtn = this.page.locator('umb-collection-pagination').getByLabel('First'); - this.nextPaginationBtn = this.page.locator('umb-collection-pagination').getByLabel('Next'); - this.nextBtn = this.page.getByLabel('Next'); - // tab: means that the tab is unnamed - this.unnamedTabTxt = page.getByTestId('tab:').getByTestId('tab:name-input').locator('#input'); - this.deleteThreeDotsBtn = page.getByLabel('Delete…'); - this.removeExactBtn = page.getByLabel('Remove', {exact: true}); - this.confirmBtn = page.getByLabel('Confirm'); - this.disableBtn = page.getByLabel('Disable', {exact: true}); - this.confirmDisableBtn = page.locator('#confirm').getByLabel('Disable'); - this.confirmToSubmitBtn = page.locator('#confirm').getByLabel('Submit'); - this.enableBtn = page.getByLabel('Enable'); - this.confirmEnableBtn = page.locator('#confirm').getByLabel('Enable'); - this.iconBtn = page.getByLabel('icon'); - this.aliasLockBtn = page.locator('#name').getByLabel('Unlock input'); - this.aliasNameTxt = page.locator('#name').getByLabel('alias'); - this.deleteFolderThreeDotsBtn = page.locator('#action-modal').getByLabel('Delete Folder...'); - this.createLink = page.getByRole('link', {name: 'Create', exact: true}); + this.allowedChildNodesModal = page.locator('umb-tree-picker-modal'); + this.addCollectionBtn = page.locator('umb-input-content-type-collection-configuration #create-button'); + + // Reorder + this.iAmDoneReorderingBtn = page.getByLabel('I am done reordering'); + this.reorderBtn = page.getByLabel('Reorder'); + + // Query Builder + this.queryBuilderBtn = page.locator('#query-builder-button'); + this.queryBuilderOrderedBy = page.locator('#property-alias-dropdown').getByLabel('Property alias'); + this.queryBuilderCreateDate = page.locator('#property-alias-dropdown').getByText('CreateDate').locator(".."); + this.queryBuilderShowCode = page.locator('umb-code-block'); + this.wherePropertyAliasBtn = page.locator('#property-alias-dropdown'); + this.whereOperatorBtn = page.locator('#operator-dropdown'); + this.whereConstrainValueTxt = page.getByLabel('constrain value'); + this.orderByPropertyAliasBtn = page.locator('#sort-dropdown'); + this.ascendingBtn = page.locator('[key="template_ascending"]'); + this.chooseRootContentBtn = page.getByLabel('Choose root document'); + this.returnedItemsCount = page.locator('#results-count'); + this.queryResults = page.locator('.query-results'); + + // Insert & Template this.insertValueBtn = page.locator('uui-button').filter({has: page.locator('[key="template_insertPageField"]')}); this.insertPartialViewBtn = page.locator('uui-button').filter({has: page.locator('[key="template_insertPartialView"]')}); this.insertDictionaryItemBtn = page.locator('uui-button').filter({has: page.locator('[key="template_insertDictionaryItem"]')}); this.chooseFieldDropDown = page.locator('#preview #expand-symbol-wrapper'); this.systemFieldsOption = page.getByText('System fields'); this.chooseFieldValueDropDown = page.locator('#value #expand-symbol-wrapper'); - this.renameBtn = page.getByRole('button', {name: /^Rename(…)?$/}); - this.returnedItemsCount = page.locator('#results-count'); - this.chooseRootContentBtn = page.getByLabel('Choose root document'); - this.queryResults = page.locator('.query-results'); - this.reloadBtn = page.getByRole('button', {name: 'Reload', exact: true}); - this.confirmToRemoveBtn = page.locator('#confirm').getByLabel('Remove'); - this.typeGroups = page.locator('umb-content-type-design-editor-group'); - this.allowedChildNodesModal = page.locator('umb-tree-picker-modal'); - this.addCollectionBtn = page.locator('umb-input-content-type-collection-configuration #create-button'); - this.errorNotification = page.locator('uui-toast-notification[open][color="danger"]'); - this.successNotification = page.locator('uui-toast-notification[open][color="positive"]'); - this.leftArrowBtn = page.locator('[name="icon-arrow-left"] svg'); - this.clickToUploadBtn = page.locator('#splitViews').getByRole('button', {name: 'Click to upload'}); - this.backOfficeHeader = page.locator('umb-backoffice-header'); + this.breadcrumbsTemplateModal = page.locator('uui-modal-sidebar').locator('umb-template-workspace-editor uui-breadcrumbs'); + + // Rename + this.newNameTxt = page.getByRole('textbox', {name: 'Enter new name...'}); + this.renameModalBtn = page.locator('umb-rename-modal').getByLabel('Rename'); + + // State & Notification + this.successState = page.locator('[state="success"]'); + this.successStateIcon = page.locator('[state="success"]').locator('#state'); this.failedStateButton = page.locator('uui-button[state="failed"]'); - this.mediaCardItems = page.locator('uui-card-media'); - this.enterPropertyEditorDescriptionTxt = this.sidebarModal.getByTestId('input:entity-description').locator('#textarea'); - this.breadcrumbsTemplateModal = this.sidebarModal.locator('umb-template-workspace-editor uui-breadcrumbs'); - this.documentTypeNode = page.locator('uui-ref-node-document-type'); - this.groupLabel = page.getByLabel('Group', {exact: true}); - this.confirmTrashBtn = page.locator('#confirm').getByLabel('Trash'); + this.successNotification = page.locator('uui-toast-notification[open][color="positive"]'); + this.errorNotification = page.locator('uui-toast-notification[open][color="danger"]'); + + // Search & Filter + this.typeToFilterSearchTxt = page.locator('[type="search"] #input'); + this.filterChooseBtn = page.locator('button').filter({hasText: 'Choose'}); + + // Text Input + this.textAreaInputArea = page.locator('textarea.ime-text-area'); + this.enterAName = page.getByLabel('Enter a name...', {exact: true}); + this.descriptionBtn = page.getByLabel('Description'); + this.enterDescriptionTxt = page.getByLabel('Enter a description...'); + this.aliasLockBtn = page.locator('#name').getByLabel('Unlock input'); + this.aliasNameTxt = page.locator('#name').getByLabel('alias'); + + // Icon + this.iconBtn = page.getByLabel('icon'); + + // Create Link + this.createLink = page.getByRole('link', {name: 'Create', exact: true}); + + // Recycle Bin this.recycleBinBtn = page.getByLabel('Recycle Bin', {exact: true}); this.recycleBinMenuItem = page.locator('uui-menu-item[label="Recycle Bin"]'); - this.recycleBinMenuItemCaretBtn = this.recycleBinMenuItem.locator('#caret-button'); + this.recycleBinMenuItemCaretBtn = page.locator('uui-menu-item[label="Recycle Bin"]').locator('#caret-button'); + + // View Options this.gridBtn = page.getByLabel('Grid'); this.listBtn = page.getByLabel('List'); this.viewBundleBtn = page.locator('umb-collection-view-bundle uui-button svg'); - this.createDocumentBlueprintModal = page.locator('umb-document-blueprint-options-create-modal'); - this.createDocumentBlueprintBtn = page.getByLabel(/^Create Document Blueprint(…)?$/); - this.createNewDocumentBlueprintBtn = this.createDocumentBlueprintModal.locator('umb-ref-item', {hasText: 'Document Blueprint for'}); - this.chooseDocumentInputBtn = page.locator('umb-input-document').getByLabel('Choose'); - this.chooseMediaInputBtn = page.locator('umb-input-media').getByLabel('Choose'); - this.container = page.locator('#container'); - this.actionBtn = page.getByTestId('workspace:action-menu-button'); + + // Media + this.mediaCardItems = page.locator('uui-card-media'); this.mediaPickerModalSubmitBtn = page.locator('umb-media-picker-modal').getByLabel('Submit'); - this.deleteBtn = page.getByRole('button', {name: /^Delete(…)?$/}); - this.createModalBtn = this.sidebarModal.getByLabel('Create', {exact: true}); this.mediaCaptionAltTextModalSubmitBtn = page.locator('umb-media-caption-alt-text-modal').getByLabel('Submit'); + this.clickToUploadBtn = page.locator('#splitViews').getByRole('button', {name: 'Click to upload'}); + this.inputDropzone = page.locator('umb-input-dropzone'); + this.imageCropperField = page.locator('umb-image-cropper-field'); + this.inputUploadField = page.locator('umb-input-upload-field').locator('#wrapperInner'); + this.chooseMediaInputBtn = page.locator('umb-input-media').getByLabel('Choose'); + + // Embedded Media this.embeddedMediaModal = page.locator('umb-embedded-media-modal'); - this.embeddedURLTxt = this.embeddedMediaModal.locator('[label="URL"] #input'); - this.embeddedRetrieveBtn = this.embeddedMediaModal.locator('[label="Retrieve"]'); - this.embeddedMediaModalConfirmBtn = this.embeddedMediaModal.getByLabel('Confirm'); - this.embeddedPreview = this.embeddedMediaModal.locator('[label="Preview"]'); - this.sectionSidebar = page.locator('umb-section-sidebar'); - this.menuItem = page.locator('uui-menu-item'); - this.property = page.locator('umb-property'); + this.embeddedURLTxt = page.locator('umb-embedded-media-modal').locator('[label="URL"] #input'); + this.embeddedRetrieveBtn = page.locator('umb-embedded-media-modal').locator('[label="Retrieve"]'); + this.embeddedMediaModalConfirmBtn = page.locator('umb-embedded-media-modal').getByLabel('Confirm'); + this.embeddedPreview = page.locator('umb-embedded-media-modal').locator('[label="Preview"]'); + + // Document & Content + this.chooseDocumentInputBtn = page.locator('umb-input-document').getByLabel('Choose'); + this.createDocumentBlueprintBtn = page.getByLabel(/^Create Document Blueprint(…)?$/); + this.createDocumentBlueprintModal = page.locator('umb-document-blueprint-options-create-modal'); + this.createNewDocumentBlueprintBtn = page.locator('umb-document-blueprint-options-create-modal').locator('umb-ref-item', {hasText: 'Document Blueprint for'}); + + // User this.currentUserAvatarBtn = page.getByTestId('header-app:Umb.HeaderApp.CurrentUser').locator('uui-avatar'); this.currentPasswordTxt = page.locator('input[name="oldPassword"]'); this.newPasswordTxt = page.locator('input[name="newPassword"]'); this.confirmPasswordTxt = page.locator('input[name="confirmPassword"]'); - this.createOptionActionListModal = page.locator('umb-entity-create-option-action-list-modal'); - this.createActionButtonCollection = page.locator('umb-collection-create-action-button'); - this.createActionBtn = this.createActionButtonCollection.locator('[label="Create"]'); + + // Collection & Table this.collectionTreeItemTableRow = page.locator('umb-collection-workspace-view umb-table uui-table-row'); - this.folderBtn = this.createOptionActionListModal.locator('umb-ref-item', {hasText: 'Folder'}); - this.reloadChildrenBtn = page.getByRole('button', {name: 'Reload children'}); + this.createActionButtonCollection = page.locator('umb-collection-create-action-button'); + this.createActionBtn = page.locator('umb-collection-create-action-button').locator('[label="Create"]'); + this.createOptionActionListModal = page.locator('umb-entity-create-option-action-list-modal'); + + // Reference & Entity this.confirmActionModalEntityReferences = page.locator('umb-confirm-action-modal-entity-references,umb-confirm-bulk-action-modal-entity-references'); - this.referenceHeadline = this.confirmActionModalEntityReferences.locator('#reference-headline').first(); - this.entityItemRef = this.confirmActionModalEntityReferences.locator('uui-ref-list').first().getByTestId('entity-item-ref'); - this.validationMessage = page.locator('umb-form-validation-message').locator('#messages'); - this.successStateIcon = this.successState.locator('#state'); + this.referenceHeadline = page.locator('umb-confirm-action-modal-entity-references,umb-confirm-bulk-action-modal-entity-references').locator('#reference-headline').first(); + this.entityItemRef = page.locator('umb-confirm-action-modal-entity-references,umb-confirm-bulk-action-modal-entity-references').locator('uui-ref-list').first().getByTestId('entity-item-ref'); + this.entityItem = page.locator('umb-entity-item-ref'); + + // Workspace & Action this.workspaceAction = page.locator('umb-workspace-action'); - this.caretBtn = page.locator('#caret-button'); - this.sectionLinks = page.getByTestId('section-links'); - // Entity Action - this.entityAction = page.locator('umb-entity-action-list umb-entity-action'); - this.openEntityAction = page.locator('#action-modal[open]').locator(this.entityAction); - // Workspace Entity Action this.workspaceActionMenuBtn = page.getByTestId('workspace:action-menu-button'); + this.entityAction = page.locator('umb-entity-action-list umb-entity-action'); + this.openEntityAction = page.locator('#action-modal[open]').locator(page.locator('umb-entity-action-list umb-entity-action')); + + // Pagination + this.firstPaginationBtn = page.locator('umb-collection-pagination').getByLabel('First'); + this.nextPaginationBtn = page.locator('umb-collection-pagination').getByLabel('Next'); + + // Editor this.monacoEditor = page.locator('.monaco-editor'); - this.openedModal = page.locator('uui-modal-container[backdrop]'); + + // Loader this.uiLoader = page.locator('uui-loader'); - this.inputDropzone = page.locator('umb-input-dropzone'); - this.imageCropperField = page.locator('umb-image-cropper-field'); - this.inputUploadField = page.locator('umb-input-upload-field').locator('#wrapperInner'); - this.entityItem = page.locator('umb-entity-item-ref'); - this.restoreBtn = page.getByLabel('Restore', {exact: true}); - this.backOfficeMain = page.locator('umb-backoffice-main'); + } + + // Helper Methods + getMenuItemByLabel(name: string): Locator { + return this.page.locator(`uui-menu-item[label="${name}"]`); } + // Actions Menu Methods async clickActionsMenuForNameInSectionSidebar(name: string) { await this.sectionSidebar.locator('[label="' + name + '"]').hover(); - await this.sectionSidebar.locator('[label="' + name + '"] >> [label="Open actions menu"]').first().click(); + await this.click(this.sectionSidebar.locator('[label="' + name + '"] >> [label="Open actions menu"]').first()); } async clickActionsMenuForName(name: string) { - await expect(this.page.locator('uui-menu-item[label="' + name + '"]').locator('#menu-item').first()).toBeVisible(); - // We need to wait for the load to be finished, otherwise we would run into flaky tests - await this.page.waitForTimeout(1000); - await this.page.locator('uui-menu-item[label="' + name + '"]').locator('#menu-item').first().hover({force: true}); - await this.page.locator('uui-menu-item[label="' + name + '"] #action-modal').first().click({force: true}); + const menuItem = this.getMenuItemByLabel(name); + await this.page.waitForTimeout(ConstantHelper.wait.medium); + await menuItem.locator('#menu-item').first().hover({force: true}); + await this.click(menuItem.locator('#action-modal').first(), {force: true}); } async isActionsMenuForNameVisible(name: string, isVisible = true) { - await this.page.locator('uui-menu-item[label="' + name + '"]').click(); - await expect(this.page.locator('uui-menu-item[label="' + name + '"] #action-modal').first()).toBeVisible({visible: isVisible}); + const menuItem = this.getMenuItemByLabel(name); + await this.click(menuItem); + await expect(menuItem.locator('#action-modal').first()).toBeVisible({visible: isVisible}); } + // Caret Button Methods async clickCaretButtonForName(name: string) { await this.isCaretButtonWithNameVisible(name); - await this.page.locator('uui-menu-item[label="' + name + '"]').locator('#caret-button').first().click(); + await this.click(this.getMenuItemByLabel(name).locator('#caret-button').first()); } async isCaretButtonWithNameVisible(name: string, isVisible = true) { - await expect(this.page.locator('uui-menu-item[label="' + name + '"]').locator('#caret-button').first()).toBeVisible({visible: isVisible}); + await expect(this.getMenuItemByLabel(name).locator('#caret-button').first()).toBeVisible({visible: isVisible}); } async clickCaretButton() { - await this.page.locator('#caret-button').click(); + await this.click(this.caretBtn); } async openCaretButtonForName(name: string, isInModal: boolean = false) { let menuItem: Locator; if (isInModal) { - menuItem = this.sidebarModal.locator('uui-menu-item[label="' + name + '"]'); + menuItem = this.sidebarModal.locator(`uui-menu-item[label="${name}"]`); } else { - menuItem = this.page.locator('uui-menu-item[label="' + name + '"]'); + menuItem = this.getMenuItemByLabel(name); } + await this.waitForVisible(menuItem, ConstantHelper.timeout.long); const isCaretButtonOpen = await menuItem.getAttribute('show-children'); - if (isCaretButtonOpen === null) { await this.clickCaretButtonForName(name); } } + // Tree Methods async reloadTree(treeName: string) { - // Waits until the tree item is visible - await expect(this.page.getByLabel(treeName, {exact: true})).toBeVisible(); - await this.page.waitForTimeout(500); + await this.isVisible(this.page.getByLabel(treeName, {exact: true})); + await this.page.waitForTimeout(ConstantHelper.wait.short); await this.clickActionsMenuForName(treeName); await this.clickReloadChildrenActionMenuOption(); - await this.openCaretButtonForName(treeName); } - async clickReloadButton() { - await expect(this.reloadBtn).toBeVisible(); - await this.reloadBtn.click(); + async isTreeItemVisible(name: string, isVisible = true) { + await this.isVisible(this.treeItem.locator('[label="' + name + '"]'), isVisible); } - async clickReloadChildrenButton() { - await expect(this.reloadChildrenBtn).toBeVisible(); - await this.reloadChildrenBtn.click({force: true}); + async doesTreeItemHaveTheCorrectIcon(name: string, icon: string) { + return await this.isVisible(this.treeItem.filter({hasText: name}).locator('umb-icon').locator('[name="' + icon + '"]')); } - async isSuccessStateVisibleForSaveButton(isVisible: boolean = true) { - const regex = new RegExp(`^workspace-action:.*Save$`); - const saveButtonLocator = this.page.getByTestId(regex); - const saveBtn = this.workspaceAction.filter({has: saveButtonLocator}); - await expect(saveBtn.locator(this.successState)).toBeVisible({visible: isVisible, timeout: 10000}); + // Core Button Click Methods + async clickReloadButton() { + await this.click(this.reloadBtn); + } + + async clickReloadChildrenButton() { + await this.click(this.reloadChildrenBtn, {force: true}); } async clickSaveButton() { - await expect(this.saveBtn).toBeVisible(); - await this.saveBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.saveBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickChooseButton() { - await expect(this.chooseBtn).toBeVisible(); - await this.chooseBtn.click(); + await this.click(this.chooseBtn); + } + + async clickChooseContainerButton() { + await this.click(this.containerChooseBtn); + } + + async clickSubmitButton() { + await this.click(this.submitBtn); + } + + async clickConfirmButton() { + await this.click(this.confirmBtn); + } + + async clickCreateButton() { + await this.click(this.createBtn); + } + + async clickAddButton() { + await this.click(this.addBtn); + } + + async clickUpdateButton() { + await this.click(this.updateBtn); + } + + async clickChangeButton() { + await this.click(this.changeBtn); + } + + async clickDeleteButton() { + await this.click(this.deleteBtn); + } + + async clickDeleteExactButton() { + await this.click(this.deleteExactBtn); } - async clickChooseContainerButton() { - await this.containerChooseBtn.click(); + async clickRemoveExactButton() { + await this.click(this.removeExactBtn); } - async clickFilterChooseButton() { - await this.filterChooseBtn.click(); + async clickInsertButton() { + await this.click(this.insertBtn); } - async clickRenameFolderThreeDotsButton() { - await this.renameFolderThreeDotsBtn.click(); + async clickRenameButton() { + await this.click(this.renameBtn); } - async clickRenameFolderButton() { - await this.clickRenameButton(); + async clickRestoreButton() { + await this.click(this.restoreBtn); } - async clickConfirmRenameButton() { - await this.confirmRenameBtn.click(); + async clickDisableButton() { + await this.click(this.disableBtn); } - async clickUpdateFolderButton() { - await this.updateFolderBtn.click(); + async clickEnableButton() { + await this.click(this.enableBtn); } - async clickUpdateButton() { - await this.updateBtn.click(); + async clickActionButton() { + await this.click(this.actionBtn); } - async clickSubmitButton() { - await expect(this.submitBtn).toBeVisible(); - await this.submitBtn.click(); + async clickNextButton() { + await this.click(this.nextBtn); } - async clickConfirmToSubmitButton() { - await this.confirmToSubmitBtn.click(); + async clickBreadcrumbButton() { + await this.click(this.breadcrumbBtn); } - async clickChangeButton() { - await this.changeBtn.click(); + async clickLeftArrowButton() { + await this.click(this.leftArrowBtn); } - async clickExactLinkWithName(name: string, toForce: boolean = false) { - const exactLinkWithNameLocator = this.page.getByRole('link', {name: name, exact: true}); - await expect(exactLinkWithNameLocator).toBeVisible(); - await exactLinkWithNameLocator.click({force: toForce}); + // Confirmation Button Methods + async clickConfirmToDeleteButton() { + await this.click(this.confirmToDeleteBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } - async enterAliasName(aliasName: string) { - // Unlocks alias - await this.page.waitForTimeout(500); - await expect(this.aliasLockBtn).toBeVisible(); - await this.aliasLockBtn.click({force: true}); - await this.aliasNameTxt.clear(); - await this.aliasNameTxt.fill(aliasName); + async clickConfirmCreateFolderButton() { + await this.click(this.confirmCreateFolderBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } - async updateIcon(iconName: string) { - await expect(this.iconBtn).toBeVisible(); - // Force click is needed - await this.iconBtn.click({force: true}); - await this.searchForTypeToFilterValue(iconName); - await this.clickLabelWithName(iconName, true, true); - await this.clickSubmitButton(); + async clickConfirmRemoveButton() { + await this.click(this.confirmToRemoveBtn); } - async clickTextButtonWithName(name: string) { - await expect(this.page.getByText(name, {exact: true})).toBeVisible(); - await this.page.getByText(name, {exact: true}).click(); + async clickConfirmToSubmitButton() { + await this.click(this.confirmToSubmitBtn); } - async clickSelectPropertyEditorButton() { - await expect(this.selectPropertyEditorBtn).toBeVisible(); - await this.selectPropertyEditorBtn.click(); + async clickConfirmDisableButton() { + await this.click(this.confirmDisableBtn); } - async clickCreateFolderButton() { - await expect(this.createFolderBtn).toBeVisible(); - await this.createFolderBtn.click(); - await this.page.waitForTimeout(500); // Wait for the action to complete + async clickConfirmEnableButton() { + await this.click(this.confirmEnableBtn); } - async enterAPropertyName(name: string) { - await expect(this.propertyNameTxt).toBeVisible(); - await this.propertyNameTxt.fill(name); + async clickConfirmRenameButton() { + await this.click(this.confirmRenameBtn); } - async clickNextPaginationButton() { - await expect(this.nextPaginationBtn).toBeVisible(); - await this.nextPaginationBtn.click(); - } - - async clickNextButton(){ - await expect(this.nextBtn).toBeVisible(); - await this.nextBtn.click(); + async clickConfirmTrashButton() { + await this.click(this.confirmTrashBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } - async clickConfirmButton() { - await expect(this.confirmBtn).toBeVisible(); - await this.confirmBtn.click(); + async clickDeleteAndConfirmButton() { + await this.clickDeleteActionMenuOption(); + await this.clickConfirmToDeleteButton(); } - async clickBreadcrumbButton() { - await expect(this.breadcrumbBtn).toBeVisible(); - await this.breadcrumbBtn.click(); + // Folder Methods + async clickCreateFolderButton() { + await this.click(this.createFolderBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } - async clickInsertButton() { - await expect(this.insertBtn).toBeVisible(); - await this.insertBtn.click(); + async enterFolderName(folderName: string) { + await this.enterText(this.folderNameTxt, folderName, {verify: true}); } - async clickConfirmToDeleteButton() { - await expect(this.confirmToDeleteBtn).toBeVisible(); - await this.confirmToDeleteBtn.click(); - await this.page.waitForTimeout(500); // Wait for the action to complete + async createFolder(folderName: string) { + await this.clickCreateActionMenuOption(); + await this.clickNewFolderThreeDotsButton(); + await this.enterFolderName(folderName); + await this.clickConfirmCreateFolderButton(); } - async clickConfirmCreateFolderButton() { - await expect(this.confirmCreateFolderBtn).toBeVisible(); - await this.confirmCreateFolderBtn.click(); - await this.page.waitForTimeout(500); // Wait for the action to complete + async deleteFolder() { + await this.clickDeleteActionMenuOption(); + await this.clickConfirmToDeleteButton(); } - async clickRemoveExactButton() { - await expect(this.removeExactBtn).toBeVisible(); - await this.removeExactBtn.click(); + async clickFolderButton() { + await this.click(this.folderBtn); } - async clickRemoveButtonForName(name: string) { - const removeButtonWithNameLocator = this.page.locator('[name="' + name + '"] [label="Remove"]'); - await expect(removeButtonWithNameLocator).toBeVisible(); - await removeButtonWithNameLocator.click(); + async clickNewFolderThreeDotsButton() { + await this.click(this.newFolderThreeDotsBtn); } - async clickTrashIconButtonForName(name: string) { - const trashIconButtonWithNameLocator = this.page.locator('[name="' + name + '"] [name="icon-trash"]'); - await expect(trashIconButtonWithNameLocator).toBeVisible(); - await trashIconButtonWithNameLocator.click(); + async clickRenameFolderThreeDotsButton() { + await this.click(this.renameFolderThreeDotsBtn); } - async clickRemoveWithName(name: string) { - const removeLabelWithNameLocator = this.page.locator('[label="Remove ' + name + '"]'); - await expect(removeLabelWithNameLocator).toBeVisible(); - await removeLabelWithNameLocator.click(); + async clickRenameFolderButton() { + await this.clickRenameButton(); } - async clickDisableButton() { - await expect(this.disableBtn).toBeVisible(); - await this.disableBtn.click(); + async clickUpdateFolderButton() { + await this.click(this.updateFolderBtn); } - async clickConfirmDisableButton() { - await expect(this.confirmDisableBtn).toBeVisible(); - await this.confirmDisableBtn.click(); + // Three Dots Menu Methods + async clickCreateThreeDotsButton() { + await this.click(this.createThreeDotsBtn); } - async clickConfirmRemoveButton() { - await expect(this.confirmToRemoveBtn).toBeVisible(); - await this.confirmToRemoveBtn.click(); + async clickFilterChooseButton() { + await this.click(this.filterChooseBtn); } - async clickEnableButton() { - await expect(this.enableBtn).toBeVisible(); - await this.enableBtn.click(); + // Success State Methods + async isSuccessStateVisibleForSaveButton(isVisible: boolean = true) { + const regex = new RegExp(`^workspace-action:.*Save$`); + const saveButtonLocator = this.page.getByTestId(regex); + const saveBtn = this.workspaceAction.filter({has: saveButtonLocator}); + await expect(saveBtn.locator(this.successState)).toBeVisible({visible: isVisible, timeout: ConstantHelper.timeout.long}); } - async clickConfirmEnableButton() { - await expect(this.confirmEnableBtn).toBeVisible(); - await this.confirmEnableBtn.click(); + async isSuccessButtonWithTextVisible(text: string) { + return await this.isVisible(this.successState.filter({hasText: text})); } - async insertDictionaryItem(dictionaryName: string) { - await this.clickInsertButton(); - await expect(this.insertDictionaryItemBtn).toBeVisible(); - await this.insertDictionaryItemBtn.click(); - await expect(this.page.getByLabel(dictionaryName)).toBeVisible(); - await this.page.getByLabel(dictionaryName).click(); - await expect(this.chooseBtn).toBeVisible(); - await this.chooseBtn.click(); + async isSuccessStateIconVisible() { + await this.isVisible(this.successStateIcon); } - async addQueryBuilderWithOrderByStatement(propertyAlias: string, isAscending: boolean) { - await expect(this.queryBuilderBtn).toBeVisible({timeout: 10000}); - await this.queryBuilderBtn.click(); - await expect(this.orderByPropertyAliasBtn).toBeVisible(); - await this.orderByPropertyAliasBtn.click(); - // Wait and choose property alias option - await this.waitAndSelectQueryBuilderDropDownList(propertyAlias); - await expect(this.orderByPropertyAliasBtn).toBeVisible(); - await this.orderByPropertyAliasBtn.click(); - // Click to ascending button if isAscending is false - if (!isAscending) { - await expect(this.ascendingBtn).toBeVisible(); - await this.ascendingBtn.click(); - } + async isFailedStateButtonVisible() { + await this.isVisible(this.failedStateButton); } - async addQueryBuilderWithWhereStatement(propertyAlias: string, operator: string, constrainValue: string) { - await expect(this.queryBuilderBtn).toBeVisible({timeout: 10000}); - await this.queryBuilderBtn.click(); - // Wait and choose property alias - await expect(this.wherePropertyAliasBtn).toBeVisible(); - await this.wherePropertyAliasBtn.click(); - await this.waitAndSelectQueryBuilderDropDownList(propertyAlias); - // Wait and choose operator - await expect(this.whereOperatorBtn).toBeVisible(); - await this.whereOperatorBtn.click(); - await this.waitAndSelectQueryBuilderDropDownList(operator); - // Wait and choose constrain value and press Enter - await expect(this.whereConstrainValueTxt).toBeVisible(); - await this.whereConstrainValueTxt.clear(); - await this.whereConstrainValueTxt.fill(constrainValue); - await this.whereConstrainValueTxt.press('Enter'); + // Notification Methods + async isSuccessNotificationVisible(isVisible: boolean = true) { + return await expect(this.successNotification.first()).toBeVisible({visible: isVisible, timeout: ConstantHelper.timeout.long}); } - async waitAndSelectQueryBuilderDropDownList(option: string) { - const ddlOption = this.page.locator('[open]').locator('uui-combobox-list-option').filter({hasText: option}).first(); - await expect(ddlOption).toBeVisible({timeout: 10000}); - await ddlOption.click(); + async doesSuccessNotificationsHaveCount(count: number) { + await this.hasCount(this.successNotification, count); } - async createFolder(folderName: string) { - await this.clickCreateActionMenuOption(); - await this.clickNewFolderThreeDotsButton(); - await this.enterFolderName(folderName); - await this.clickConfirmCreateFolderButton(); + async doesSuccessNotificationHaveText(text: string, isVisible: boolean = true, deleteNotification = false, timeout = 5000) { + const response = await expect(this.successNotification.filter({hasText: text})).toBeVisible({ + visible: isVisible, + timeout: timeout + }); + if (deleteNotification) { + await this.click(this.successNotification.filter({hasText: text}).getByLabel('close'), {force: true}); + } + return response; } - async deletePropertyEditor(propertyEditorName: string) { - // We need to hover over the property to be able to see the delete button - await this.page.locator('uui-button').filter({hasText: propertyEditorName}).getByLabel('Editor settings').hover(); - await this.deleteBtn.click(); + async isErrorNotificationVisible(isVisible: boolean = true) { + return await expect(this.errorNotification.first()).toBeVisible({visible: isVisible}); } - async enterFolderName(folderName: string) { - await expect(this.folderNameTxt).toBeVisible(); - await this.folderNameTxt.clear(); - await this.folderNameTxt.fill(folderName); - await expect(this.folderNameTxt).toHaveValue(folderName); + async doesErrorNotificationHaveText(text: string, isVisible: boolean = true, deleteNotification: boolean = false) { + const response = await expect(this.errorNotification.filter({hasText: text})).toBeVisible({visible: isVisible}); + if (deleteNotification) { + await this.click(this.errorNotification.filter({hasText: text}).locator('svg')); + } + return response; } - async isTextWithExactNameVisible(name: string, isVisible = true) { - return expect(this.page.getByText(name, {exact: true})).toBeVisible({visible: isVisible}); + // Modal Methods + async clickChooseModalButton() { + await this.click(this.chooseModalBtn); } - async isQueryBuilderCodeShown(code: string) { - await expect(this.queryBuilderShowCode).toBeVisible(); - await this.queryBuilderShowCode.click(); - await expect(this.queryBuilderShowCode).toContainText(code, {timeout: 10000}); + async clickCreateModalButton() { + await this.click(this.createModalBtn); } - async deleteFolder() { - await this.clickDeleteActionMenuOption(); - await this.clickConfirmToDeleteButton(); + async clickModalMenuItemWithName(name: string) { + await this.click(this.openedModal.locator(`uui-menu-item[label="${name}"]`), {timeout: ConstantHelper.timeout.long}); } - async clickDeleteExactButton() { - await expect(this.deleteExactBtn).toBeVisible(); - await this.deleteExactBtn.click(); + async isModalMenuItemWithNameDisabled(name: string) { + await this.hasAttribute(this.sidebarModal.locator(`uui-menu-item[label="${name}"]`), 'disabled', ''); } - async isTreeItemVisible(name: string, isVisible = true) { - await expect(this.page.locator('umb-tree-item').locator('[label="' + name + '"]')).toBeVisible({visible: isVisible}); + async isModalMenuItemWithNameVisible(name: string, isVisible: boolean = true) { + await this.isVisible(this.sidebarModal.locator(`uui-menu-item[label="${name}"]`), isVisible); } - async doesTreeItemHaveTheCorrectIcon(name: string, icon: string) { - return await expect(this.page.locator('umb-tree-item').filter({hasText: name}).locator('umb-icon').locator('[name="' + icon + '"]')).toBeVisible(); + // Container Methods + async clickContainerSaveAndPublishButton() { + await this.click(this.containerSaveAndPublishBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } + // Navigation Methods async goToSection(sectionName: string, checkSections = true, skipReload = false) { if (checkSections) { for (let section in ConstantHelper.sections) { - await expect(this.sectionLinks.getByRole('tab', {name: ConstantHelper.sections[section]})).toBeVisible({timeout: 30000}); + await expect(this.sectionLinks.getByRole('tab', {name: ConstantHelper.sections[section]})).toBeVisible({timeout: ConstantHelper.timeout.navigation}); } } - - // We need to check if we are on the section tab already, if we are, then we need to reload the page instead of clicking again const alreadySelected = await this.sectionLinks.locator('[active]').getByText(sectionName).isVisible(); if (alreadySelected && !skipReload) { await this.page.reload(); } else { - await this.backOfficeHeader.getByRole('tab', {name: sectionName}).click(); + await this.click(this.backOfficeHeader.getByRole('tab', {name: sectionName})); } } async goToSettingsTreeItem(settingsTreeItemName: string) { await this.goToSection(ConstantHelper.sections.settings); - await expect(this.page.getByLabel(settingsTreeItemName, {exact: true})).toBeVisible(); - await this.page.getByLabel(settingsTreeItemName, {exact: true}).click(); + await this.click(this.page.getByLabel(settingsTreeItemName, {exact: true})); } - async clickDataElement(elementName: string, options: any = null) { - await this.page.click(`[data-element="${elementName}"]`, options); + async isSectionWithNameVisible(sectionName: string, isVisible: boolean = true) { + await this.isVisible(this.page.getByRole('tab', {name: sectionName}), isVisible); } - async getDataElement(elementName: string) { - return this.page.locator(`[data-element="${elementName}"]`); + async isBackOfficeMainVisible(isVisible: boolean = true) { + await this.page.waitForTimeout(ConstantHelper.timeout.medium); + await this.isVisible(this.backOfficeMain, isVisible); } - async isButtonWithNameVisible(name: string) { - await expect(this.page.getByRole('button', {name: name})).toBeVisible(); + // Link & Button Click by Name Methods + async clickExactLinkWithName(name: string, toForce: boolean = false) { + const exactLinkWithNameLocator = this.page.getByRole('link', {name: name, exact: true}); + await this.click(exactLinkWithNameLocator, {force: toForce}); + } + + async clickLinkWithName(name: string, isExact: boolean = false) { + await this.click(this.page.getByRole('link', {name: name, exact: isExact})); } async clickLabelWithName(name: string, isExact: boolean = true, toForce: boolean = false) { - await expect(this.page.getByLabel(name, {exact: isExact})).toBeVisible(); - await this.page.getByLabel(name, {exact: isExact}).click({force: toForce}); + await this.click(this.page.getByLabel(name, {exact: isExact}), {force: toForce}); } async clickButtonWithName(name: string, isExact: boolean = false) { const exactButtonWithNameLocator = this.page.getByRole('button', {name: name, exact: isExact}); - await expect(exactButtonWithNameLocator).toBeVisible(); - // Force click is needed - await exactButtonWithNameLocator.click({force: true}); + await this.click(exactButtonWithNameLocator, {force: true}); } - async isSuccessNotificationVisible(isVisible: boolean = true) { - return await expect(this.successNotification.first()).toBeVisible({visible: isVisible, timeout: 10000}); + async clickTextButtonWithName(name: string) { + await this.click(this.page.getByText(name, {exact: true})); } - async doesSuccessNotificationsHaveCount(count: number) { - return await expect(this.successNotification).toHaveCount(count); + async isButtonWithNameVisible(name: string) { + await this.isVisible(this.page.getByRole('button', {name: name})); } - async isErrorNotificationVisible(isVisible: boolean = true) { - return await expect(this.errorNotification.first()).toBeVisible({visible: isVisible}); + async getButtonWithName(name: string) { + await this.waitForVisible(this.page.getByRole('button', {name: name})); + return this.page.getByRole('button', {name: name}); } - async isTextWithMessageVisible(message: string, isVisible: boolean = true) { - return await expect(this.page.getByText(message)).toBeVisible({visible: isVisible}); + // Remove Button Methods + async clickRemoveButtonForName(name: string) { + const removeButtonWithNameLocator = this.page.locator('[name="' + name + '"] [label="Remove"]'); + await this.click(removeButtonWithNameLocator); } - async clickCreateThreeDotsButton() { - await expect(this.createThreeDotsBtn).toBeVisible(); - await this.createThreeDotsBtn.click(); + async clickTrashIconButtonForName(name: string) { + const trashIconButtonWithNameLocator = this.page.locator('[name="' + name + '"] [name="icon-trash"]'); + await this.click(trashIconButtonWithNameLocator); } - async clickCreateButton() { - await expect(this.createBtn).toBeVisible(); - await this.createBtn.click(); + async clickRemoveWithName(name: string) { + const removeLabelWithNameLocator = this.page.locator('[label="Remove ' + name + '"]'); + await this.click(removeLabelWithNameLocator); } - async clickAddButton() { - await expect(this.addBtn).toBeVisible(); - await this.addBtn.click(); - }; + // Alias & Icon Methods + async enterAliasName(aliasName: string) { + await this.page.waitForTimeout(ConstantHelper.wait.short); + await this.click(this.aliasLockBtn, {force: true}); + await this.enterText(this.aliasNameTxt, aliasName); + } - async clickNewFolderThreeDotsButton() { - await expect(this.newFolderThreeDotsBtn).toBeVisible(); - await this.newFolderThreeDotsBtn.click(); + async updateIcon(iconName: string) { + await this.click(this.iconBtn, {force: true}); + await this.searchForTypeToFilterValue(iconName); + await this.clickLabelWithName(iconName, true, true); + await this.clickSubmitButton(); + } + + // Property Editor Methods + async clickSelectPropertyEditorButton() { + await this.click(this.selectPropertyEditorBtn); + } + + async enterAPropertyName(name: string) { + await this.enterText(this.propertyNameTxt, name, {clearFirst: false}); } async clickEditorSettingsButton(index: number = 0) { - await expect(this.editorSettingsBtn.nth(index)).toBeVisible(); - return this.editorSettingsBtn.nth(index).click(); + await this.click(this.editorSettingsBtn.nth(index)); } - async enterDescription(description: string) { - await expect(this.enterDescriptionTxt).toBeVisible(); - await this.enterDescriptionTxt.clear(); - await this.enterDescriptionTxt.fill(description); + async addPropertyEditor(propertyEditorName: string, index: number = 0) { + await this.click(this.addPropertyBtn.nth(index)); + await this.enterAPropertyName(propertyEditorName); + await this.hasValue(this.propertyNameTxt, propertyEditorName); + await this.clickSelectPropertyEditorButton(); + await this.searchForTypeToFilterValue(propertyEditorName); + await this.click(this.page.getByText(propertyEditorName, {exact: true})); + await this.clickSubmitButton(); } - async doesDescriptionHaveValue(value: string, index: number = 0) { - return await expect(this.descriptionBtn.nth(index)).toHaveValue(value); + async updatePropertyEditor(propertyEditorName: string) { + await this.clickEditorSettingsButton(); + await this.clickChangeButton(); + await this.searchForTypeToFilterValue(propertyEditorName); + await this.click(this.page.getByText(propertyEditorName, {exact: true})); + await this.enterAPropertyName(propertyEditorName); + await this.clickSubmitButton(); } - async clickStructureTab() { - await this.page.waitForTimeout(1000); - await expect(this.structureTabBtn).toBeVisible(); - await this.structureTabBtn.click(); + async deletePropertyEditor(propertyEditorName: string) { + await this.page.locator('uui-button').filter({hasText: propertyEditorName}).getByLabel('Editor settings').hover(); + await this.click(this.deleteBtn); } - async clickAllowAtRootButton() { - await expect(this.allowAtRootBtn).toBeVisible(); - await this.allowAtRootBtn.click(); + async deletePropertyEditorWithName(name: string) { + const propertyEditor = this.page.locator('umb-content-type-design-editor-property', {hasText: name}); + await this.hoverAndClick(propertyEditor, propertyEditor.getByLabel('Delete'), {force: true}); + await this.clickConfirmToDeleteButton(); } - async clickIAmDoneReorderingButton() { - await expect(this.iAmDoneReorderingBtn).toBeVisible(); - await this.iAmDoneReorderingBtn.click(); + async enterPropertyEditorDescription(description: string) { + await this.enterText(this.enterPropertyEditorDescriptionTxt, description); } - async clickReorderButton() { - await expect(this.reorderBtn).toBeVisible(); - await this.reorderBtn.click(); + async isPropertyEditorUiWithNameReadOnly(name: string) { + const propertyEditorUiLocator = this.page.locator('umb-property-editor-ui-' + name); + await this.hasAttribute(propertyEditorUiLocator, 'readonly', ''); } - async clickLabelAboveButton() { - await expect(this.labelAboveBtn).toBeVisible(); - await this.labelAboveBtn.click(); + async isPropertyEditorUiWithNameVisible(name: string, isVisible: boolean = true) { + const propertyEditorUiLocator = this.page.locator('umb-property-editor-ui-' + name); + await this.isVisible(propertyEditorUiLocator, isVisible); } - async clickMandatoryToggle() { - await expect(this.mandatoryToggle).toBeVisible(); - await this.mandatoryToggle.click(); + async doesPropertyHaveInvalidBadge(propertyName: string) { + await this.isVisible(this.page.locator('umb-property-layout').filter({hasText: propertyName}).locator('#invalid-badge uui-badge')); } - async selectValidationOption(option: string) { - await expect(this.validation).toBeVisible(); - await this.validation.selectOption(option); + // Group Methods + async clickAddGroupButton() { + await this.click(this.addGroupBtn); } - async enterRegEx(regEx: string) { - await expect(this.regexTxt).toBeVisible(); - await this.regexTxt.fill(regEx); + async enterGroupName(groupName: string, index: number = 0) { + const groupNameTxt = this.groupLabel.nth(index); + await this.enterText(groupNameTxt, groupName); } - async enterRegExMessage(regExMessage: string) { - await expect(this.regexMessageTxt).toBeVisible(); - await this.regexMessageTxt.fill(regExMessage); + async isGroupVisible(groupName: string, isVisible = true) { + await this.isVisible(this.groupLabel.filter({hasText: groupName}), isVisible); } - async clickCompositionsButton() { - await expect(this.compositionsBtn).toBeVisible(); - await this.compositionsBtn.click(); + async doesGroupHaveValue(value: string) { + await this.waitForVisible(this.groupLabel); + return await this.hasValue(this.groupLabel, value); } - async clickAddTabButton() { - await expect(this.addTabBtn).toBeVisible(); - await this.addTabBtn.click(); + async deleteGroup(groupName: string) { + await this.page.waitForTimeout(ConstantHelper.wait.medium); + const groups = this.page.locator('umb-content-type-design-editor-group').all(); + for (const group of await groups) { + if (await group.getByLabel('Group', {exact: true}).inputValue() === groupName) { + const headerActionsDeleteLocator = group.locator('[slot="header-actions"]').getByLabel('Delete'); + await this.click(headerActionsDeleteLocator, {force: true}); + return; + } + } } - async enterTabName(tabName: string) { - await expect(this.unnamedTabTxt).toBeVisible(); - await this.page.waitForTimeout(400); - await this.unnamedTabTxt.clear(); - await this.unnamedTabTxt.fill(tabName); - // We use this to make sure the test id is updated - await this.page.getByRole('tab', {name: 'Design'}).click(); - // We click again to make sure the tab is focused - await this.page.getByTestId('tab:' + tabName).click(); + async reorderTwoGroups(firstGroupName: string, secondGroupName: string) { + const firstGroup = this.page.getByTestId('group:' + firstGroupName); + const secondGroup = this.page.getByTestId('group:' + secondGroupName); + const firstGroupValue = await firstGroup.getByLabel('Group').inputValue(); + const secondGroupValue = await secondGroup.getByLabel('Group').inputValue(); + const dragToLocator = firstGroup.locator('[slot="header"]').first(); + const dragFromLocator = secondGroup.locator('[slot="header"]').first(); + await this.dragAndDrop(dragFromLocator, dragToLocator, 0, 0, 20); + return {firstGroupValue, secondGroupValue}; } - async searchForTypeToFilterValue(searchValue: string) { - await expect(this.typeToFilterSearchTxt).toBeVisible(); - await this.typeToFilterSearchTxt.fill(searchValue); + // Tab Methods + async clickAddTabButton() { + await this.click(this.addTabBtn); } - async addPropertyEditor(propertyEditorName: string, index: number = 0) { - await expect(this.addPropertyBtn.nth(index)).toBeVisible(); - await this.addPropertyBtn.nth(index).click(); - await this.enterAPropertyName(propertyEditorName); - await expect(this.propertyNameTxt).toHaveValue(propertyEditorName); - await this.clickSelectPropertyEditorButton(); - await this.searchForTypeToFilterValue(propertyEditorName); - await this.page.getByText(propertyEditorName, {exact: true}).click(); - await this.clickSubmitButton(); + async enterTabName(tabName: string) { + await this.waitForVisible(this.unnamedTabTxt); + await this.page.waitForTimeout(ConstantHelper.wait.debounce); + await this.enterText(this.unnamedTabTxt, tabName); + await this.click(this.page.getByRole('tab', {name: 'Design'})); + await this.click(this.page.getByTestId('tab:' + tabName)); } - async updatePropertyEditor(propertyEditorName: string) { - await this.clickEditorSettingsButton(); - await this.clickChangeButton(); - await this.searchForTypeToFilterValue(propertyEditorName); - await this.page.getByText(propertyEditorName, {exact: true}).click(); - await this.enterAPropertyName(propertyEditorName); - await this.clickSubmitButton(); + async clickRemoveTabWithName(name: string) { + const tab = this.page.locator('uui-tab').filter({hasText: name}); + await this.hoverAndClick(tab, tab.locator('[label="Remove"]')); } - async enterPropertyEditorDescription(description: string) { - await expect(this.enterPropertyEditorDescriptionTxt).toBeVisible(); - await this.enterPropertyEditorDescriptionTxt.clear(); - await this.enterPropertyEditorDescriptionTxt.fill(description); + async clickStructureTab() { + await this.page.waitForTimeout(ConstantHelper.wait.medium); + await this.click(this.structureTabBtn); } - async clickAddGroupButton() { - await expect(this.addGroupBtn).toBeVisible(); - await this.addGroupBtn.click(); + getTabLocatorWithName(name: string) { + return this.page.getByRole('tab', {name: name}); } - async clickChooseModalButton() { - await expect(this.chooseModalBtn).toBeVisible(); - await this.chooseModalBtn.click(); + // Validation Methods + async clickMandatoryToggle() { + await this.click(this.mandatoryToggle); } - async enterGroupName(groupName: string, index: number = 0) { - const groupNameTxt = this.groupLabel.nth(index); - await expect(groupNameTxt).toBeVisible(); - await groupNameTxt.clear(); - await groupNameTxt.fill(groupName); + async selectValidationOption(option: string) { + await this.selectByValue(this.validation, option); } - async isGroupVisible(groupName: string, isVisible = true) { - await expect(this.groupLabel.filter({hasText: groupName})).toBeVisible({visible: isVisible}); + async enterRegEx(regEx: string) { + await this.enterText(this.regexTxt, regEx, {clearFirst: false}); } - async doesGroupHaveValue(value: string) { - await expect(this.groupLabel).toBeVisible(); - return await expect(this.groupLabel).toHaveValue(value); + async enterRegExMessage(regExMessage: string) { + await this.enterText(this.regexMessageTxt, regExMessage, {clearFirst: false}); } - async rename(newName: string) { - await this.clickRenameActionMenuOption(); - await expect(this.newNameTxt).toBeVisible(); - await this.newNameTxt.click(); - await this.newNameTxt.clear(); - await this.newNameTxt.fill(newName); - await this.renameModalBtn.click(); - await this.page.waitForTimeout(500); + async isValidationMessageVisible(message: string, isVisible: boolean = true) { + await this.isVisible(this.validationMessage.filter({hasText: message}), isVisible); } - async isSuccessButtonWithTextVisible(text: string) { - return await expect(this.successState.filter({hasText: text})).toBeVisible(); + // Composition & Structure Methods + async clickCompositionsButton() { + await this.click(this.compositionsBtn); } - async dragAndDrop(dragFromSelector: Locator, dragToSelector: Locator, verticalOffset: number = 0, horizontalOffset: number = 0, steps: number = 5) { - await expect(dragFromSelector).toBeVisible(); - await expect(dragToSelector).toBeVisible(); - const targetLocation = await dragToSelector.boundingBox(); - const elementCenterX = targetLocation!.x + targetLocation!.width / 2; - const elementCenterY = targetLocation!.y + targetLocation!.height / 2; - await dragFromSelector.hover(); - await this.page.mouse.move(10, 10); - await dragFromSelector.hover(); - await this.page.mouse.down(); - await this.page.waitForTimeout(400); - await this.page.mouse.move(elementCenterX + horizontalOffset, elementCenterY + verticalOffset, {steps: steps}); - await this.page.waitForTimeout(400); - await this.page.mouse.up(); + async clickAllowAtRootButton() { + await this.click(this.allowAtRootBtn); } - async getButtonWithName(name: string) { - await expect(this.page.getByRole('button', {name: name})).toBeVisible(); - return this.page.getByRole('button', {name: name}); + async clickAllowedChildNodesButton() { + await this.click(this.allowedChildNodesModal.locator(this.chooseBtn)); } - async clickCreateLink() { - await expect(this.createLink).toBeVisible(); - await this.createLink.click(); + async clickAddCollectionButton() { + await this.click(this.addCollectionBtn); } - async insertSystemFieldValue(fieldValue: string) { - await this.clickInsertButton(); - await expect(this.insertValueBtn).toBeVisible(); - await this.insertValueBtn.click(); - await expect(this.chooseFieldDropDown).toBeVisible(); - await this.chooseFieldDropDown.click(); - await expect(this.systemFieldsOption).toBeVisible(); - await this.systemFieldsOption.click(); - await expect(this.chooseFieldValueDropDown).toBeVisible(); - await this.chooseFieldValueDropDown.click(); - await expect(this.page.getByText(fieldValue)).toBeVisible(); - await this.page.getByText(fieldValue).click(); - await this.clickSubmitButton(); + // Reorder Methods + async clickIAmDoneReorderingButton() { + await this.click(this.iAmDoneReorderingBtn); } - async insertPartialView(partialViewName: string) { - await this.clickInsertButton(); - await expect(this.insertPartialViewBtn).toBeVisible(); - await this.insertPartialViewBtn.click(); - await expect(this.page.getByLabel(partialViewName)).toBeVisible(); - await this.page.getByLabel(partialViewName).click(); - await this.clickChooseButton(); + async clickReorderButton() { + await this.click(this.reorderBtn); } - async deletePropertyEditorWithName(name: string) { - // We need to hover over the Property Editor to make the delete button visible - const propertyEditor = this.page.locator('umb-content-type-design-editor-property', {hasText: name}); - await expect(propertyEditor).toBeVisible(); - await propertyEditor.hover(); - await expect(propertyEditor.getByLabel('Delete')).toBeVisible(); - // Force click is needed - await propertyEditor.getByLabel('Delete').click({force: true}); - await this.clickConfirmToDeleteButton(); + async clickLabelAboveButton() { + await this.click(this.labelAboveBtn); } - async clickRenameButton() { - await expect(this.renameBtn).toBeVisible(); - await this.renameBtn.click(); + // Query Builder Methods + async clickQueryBuilderButton() { + await this.click(this.queryBuilderBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } - async clickDeleteAndConfirmButton() { - await this.clickDeleteActionMenuOption(); - await this.clickConfirmToDeleteButton(); + async addQueryBuilderWithOrderByStatement(propertyAlias: string, isAscending: boolean) { + await this.click(this.queryBuilderBtn, {timeout: ConstantHelper.timeout.long}); + await this.click(this.orderByPropertyAliasBtn); + await this.waitAndSelectQueryBuilderDropDownList(propertyAlias); + await this.click(this.orderByPropertyAliasBtn); + if (!isAscending) { + await this.click(this.ascendingBtn); + } } - async clickDeleteButton() { - await expect(this.deleteBtn).toBeVisible(); - await this.deleteBtn.click(); + async addQueryBuilderWithWhereStatement(propertyAlias: string, operator: string, constrainValue: string) { + await this.click(this.queryBuilderBtn, {timeout: ConstantHelper.timeout.long}); + await this.click(this.wherePropertyAliasBtn); + await this.waitAndSelectQueryBuilderDropDownList(propertyAlias); + await this.click(this.whereOperatorBtn); + await this.waitAndSelectQueryBuilderDropDownList(operator); + await this.enterText(this.whereConstrainValueTxt, constrainValue); + await this.pressKey(this.whereConstrainValueTxt, 'Enter'); } - async clickQueryBuilderButton() { - await expect(this.queryBuilderBtn).toBeVisible(); - await this.queryBuilderBtn.click(); - await this.page.waitForTimeout(500); + async waitAndSelectQueryBuilderDropDownList(option: string) { + const ddlOption = this.page.locator('[open]').locator('uui-combobox-list-option').filter({hasText: option}).first(); + await this.click(ddlOption, {timeout: ConstantHelper.timeout.long}); } async chooseRootContentInQueryBuilder(contentName: string) { - await expect(this.chooseRootContentBtn).toBeVisible(); - await this.chooseRootContentBtn.click(); + await this.click(this.chooseRootContentBtn); await this.clickModalMenuItemWithName(contentName); await this.clickChooseButton(); } - async reorderTwoGroups(firstGroupName: string, secondGroupName: string) { - const firstGroup = this.page.getByTestId('group:' + firstGroupName); - const secondGroup = this.page.getByTestId('group:' + secondGroupName); - const firstGroupValue = await firstGroup.getByLabel('Group').inputValue(); - const secondGroupValue = await secondGroup.getByLabel('Group').inputValue(); - const dragToLocator = firstGroup.locator('[slot="header"]').first(); - const dragFromLocator = secondGroup.locator('[slot="header"]').first(); - await this.dragAndDrop(dragFromLocator, dragToLocator, 0, 0, 20); - return {firstGroupValue, secondGroupValue}; - } - - async clickAllowedChildNodesButton() { - await expect(this.allowedChildNodesModal.locator(this.chooseBtn)).toBeVisible(); - await this.allowedChildNodesModal.locator(this.chooseBtn).click(); - } - - async clickAddCollectionButton() { - await expect(this.addCollectionBtn).toBeVisible(); - await this.addCollectionBtn.click(); + async isQueryBuilderCodeShown(code: string) { + await this.click(this.queryBuilderShowCode); + await this.containsText(this.queryBuilderShowCode, code, ConstantHelper.timeout.long); } async doesReturnedItemsHaveCount(itemCount: number) { - await expect(this.returnedItemsCount).toContainText(itemCount.toString() + ' published items returned'); + await this.containsText(this.returnedItemsCount, itemCount.toString() + ' published items returned'); } async doesQueryResultHaveContentName(contentName: string) { - await expect(this.queryResults).toContainText(contentName); + await this.containsText(this.queryResults, contentName); } - async deleteGroup(groupName: string) { - await this.page.waitForTimeout(1000); - const groups = this.page.locator('umb-content-type-design-editor-group').all(); - for (const group of await groups) { - if (await group.getByLabel('Group', {exact: true}).inputValue() === groupName) { - const headerActionsDeleteLocator = group.locator('[slot="header-actions"]').getByLabel('Delete'); - await expect(headerActionsDeleteLocator).toBeVisible(); - // Force click is needed - await headerActionsDeleteLocator.click({force: true}); - return; - } - } + // Insert Methods + async insertDictionaryItem(dictionaryName: string) { + await this.clickInsertButton(); + await this.click(this.insertDictionaryItemBtn); + await this.click(this.page.getByLabel(dictionaryName)); + await this.click(this.chooseBtn); } - async clickRemoveTabWithName(name: string) { - await expect(this.page.locator('uui-tab').filter({hasText: name})).toBeVisible(); - await this.page.locator('uui-tab').filter({hasText: name}).hover(); - const removeTabWithNameLocator = this.page.locator('uui-tab').filter({hasText: name}).locator('[label="Remove"]'); - await expect(removeTabWithNameLocator).toBeVisible(); - await removeTabWithNameLocator.click(); + async insertSystemFieldValue(fieldValue: string) { + await this.clickInsertButton(); + await this.click(this.insertValueBtn); + await this.click(this.chooseFieldDropDown); + await this.click(this.systemFieldsOption); + await this.click(this.chooseFieldValueDropDown); + await this.click(this.page.getByText(fieldValue)); + await this.clickSubmitButton(); } - async clickLeftArrowButton() { - await expect(this.leftArrowBtn).toBeVisible(); - await this.leftArrowBtn.click(); + async insertPartialView(partialViewName: string) { + await this.clickInsertButton(); + await this.click(this.insertPartialViewBtn); + await this.click(this.page.getByLabel(partialViewName)); + await this.clickChooseButton(); } - async clickToUploadButton() { - await expect(this.clickToUploadBtn).toBeVisible(); - await this.clickToUploadBtn.click(); + // Rename Methods + async rename(newName: string) { + await this.clickRenameActionMenuOption(); + await this.click(this.newNameTxt); + await this.enterText(this.newNameTxt, newName); + await this.click(this.renameModalBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } - async uploadFile(filePath: string) { - const [fileChooser] = await Promise.all([ - this.page.waitForEvent('filechooser'), - await this.clickToUploadButton(), - ]); - await fileChooser.setFiles(filePath); + // Search & Filter Methods + async searchForTypeToFilterValue(searchValue: string) { + await this.enterText(this.typeToFilterSearchTxt, searchValue, {clearFirst: false}); } - getTabLocatorWithName(name: string) { - return this.page.getByRole('tab', {name: name}); + // Description Methods + async enterDescription(description: string) { + await this.enterText(this.enterDescriptionTxt, description); } - getTextLocatorWithName(name: string) { - return this.page.getByText(name, {exact: true}); + async doesDescriptionHaveValue(value: string, index: number = 0) { + return await this.hasValue(this.descriptionBtn.nth(index), value); } - getLocatorWithDataMark(dataMark: string) { - return this.page.getByTestId(dataMark); - }; - - async isFailedStateButtonVisible() { - await expect(this.failedStateButton).toBeVisible(); + // Drag and Drop Methods + async dragAndDrop(dragFromSelector: Locator, dragToSelector: Locator, verticalOffset: number = 0, horizontalOffset: number = 0, steps: number = 5) { + await this.waitForVisible(dragFromSelector); + await this.waitForVisible(dragToSelector); + const targetLocation = await dragToSelector.boundingBox(); + const elementCenterX = targetLocation!.x + targetLocation!.width / 2; + const elementCenterY = targetLocation!.y + targetLocation!.height / 2; + await this.hover(dragFromSelector); + await this.page.mouse.move(10, 10); + await this.hover(dragFromSelector); + await this.page.mouse.down(); + await this.page.waitForTimeout(ConstantHelper.wait.debounce); + await this.page.mouse.move(elementCenterX + horizontalOffset, elementCenterY + verticalOffset, {steps: steps}); + await this.page.waitForTimeout(ConstantHelper.wait.debounce); + await this.page.mouse.up(); } - async clickContainerSaveAndPublishButton() { - await expect(this.containerSaveAndPublishBtn).toBeVisible(); - await this.containerSaveAndPublishBtn.click(); - await this.page.waitForTimeout(500); + // Create Link Methods + async clickCreateLink() { + await this.click(this.createLink); } - async clickConfirmTrashButton() { - await expect(this.confirmTrashBtn).toBeVisible(); - await this.confirmTrashBtn.click(); - await this.page.waitForTimeout(500); + // Recycle Bin Methods + async clickRecycleBinButton() { + await this.click(this.recycleBinBtn); } async reloadRecycleBin(containsItems = true) { - await expect(this.recycleBinMenuItem).toBeVisible(); - // If the Recycle Bin does not contain any items,0 the caret button should not be visible. and we should not try to click it + await this.waitForVisible(this.recycleBinMenuItem); if (!containsItems) { await this.clickReloadChildrenActionMenuOption(); - await expect(this.recycleBinMenuItemCaretBtn).not.toBeVisible(); + await this.isVisible(this.recycleBinMenuItemCaretBtn, false); return; } - await this.clickActionsMenuForName('Recycle Bin'); await this.clickReloadChildrenActionMenuOption(); - await this.openCaretButtonForName('Recycle Bin'); } - async clickRecycleBinButton() { - await expect(this.recycleBinBtn).toBeVisible(); - await this.recycleBinBtn.click(); - } - async isItemVisibleInRecycleBin(item: string, isVisible: boolean = true, isReload: boolean = true) { if (isReload) { await this.reloadRecycleBin(isVisible); } - return await expect(this.page.locator('[label="Recycle Bin"] [label="' + item + '"]')).toBeVisible({visible: isVisible}); + return await this.isVisible(this.page.locator('[label="Recycle Bin"] [label="' + item + '"]'), isVisible); } + // View Methods async changeToGridView() { - await expect(this.viewBundleBtn).toBeVisible(); - await this.viewBundleBtn.click(); - await this.gridBtn.click(); + await this.click(this.viewBundleBtn); + await this.click(this.gridBtn); } async changeToListView() { - await expect(this.viewBundleBtn).toBeVisible(); - await this.viewBundleBtn.click(); - await this.listBtn.click(); + await this.click(this.viewBundleBtn); + await this.click(this.listBtn); } async isViewBundleButtonVisible(isVisible: boolean = true) { - return expect(this.viewBundleBtn).toBeVisible({visible: isVisible}); + return this.isVisible(this.viewBundleBtn, isVisible); } - async doesSuccessNotificationHaveText(text: string, isVisible: boolean = true, deleteNotification = false, timeout = 5000) { - const response = await expect(this.successNotification.filter({hasText: text})).toBeVisible({ - visible: isVisible, - timeout: timeout - }); - if (deleteNotification) { - await this.successNotification.filter({hasText: text}).getByLabel('close').click({force: true}); - } - return response; + // Media Methods + async clickMediaWithName(name: string) { + await this.click(this.mediaCardItems.filter({hasText: name})); } - async doesErrorNotificationHaveText(text: string, isVisible: boolean = true, deleteNotification: boolean = false) { - const response = await expect(this.errorNotification.filter({hasText: text})).toBeVisible({visible: isVisible}); - if (deleteNotification) { - await this.errorNotification.filter({hasText: text}).locator('svg').click(); - } - return response; + async selectMediaWithName(mediaName: string, isForce: boolean = false) { + const mediaLocator = this.mediaCardItems.filter({hasText: mediaName}); + await this.waitForVisible(mediaLocator); + // Using direct click with position option (not supported by BasePage.click) + await mediaLocator.click({position: {x: 0.5, y: 0.5}, force: isForce}); } - async isSectionWithNameVisible(sectionName: string, isVisible: boolean = true) { - await expect(this.page.getByRole('tab', {name: sectionName})).toBeVisible({visible: isVisible}); + async selectMediaWithTestId(mediaKey: string) { + const locator = this.page.getByTestId('media:' + mediaKey); + await this.waitForVisible(locator); + // Using direct click with position option (not supported by BasePage.click) + await locator.click({position: {x: 0.5, y: 0.5}}); } - async clickMediaWithName(name: string) { - await expect(this.mediaCardItems.filter({hasText: name})).toBeVisible(); - await this.mediaCardItems.filter({hasText: name}).click(); + async clickMediaPickerModalSubmitButton() { + await this.click(this.mediaPickerModalSubmitBtn); } - async clickChooseContentStartNodeButton() { - await expect(this.chooseDocumentInputBtn).toBeVisible(); - await this.chooseDocumentInputBtn.click(); + async clickMediaCaptionAltTextModalSubmitButton() { + await this.click(this.mediaCaptionAltTextModalSubmitBtn); } async clickChooseMediaStartNodeButton() { - await expect(this.chooseMediaInputBtn).toBeVisible(); - await this.chooseMediaInputBtn.click(); + await this.click(this.chooseMediaInputBtn); } - async clickActionButton() { - await expect(this.actionBtn).toBeVisible(); - await this.actionBtn.click(); + async isMediaCardItemWithNameDisabled(itemName: string) { + await this.hasAttribute(this.mediaCardItems.filter({hasText: itemName}), 'class', 'not-allowed'); } - async clickReferenceNodeLinkWithName(name: string) { - await expect(this.page.locator('[name="' + name + '"] a#open-part')).toBeVisible(); - await this.page.locator('[name="' + name + '"] a#open-part').click(); + async isMediaCardItemWithNameVisible(itemName: string, isVisible: boolean = true) { + await this.isVisible(this.mediaCardItems.filter({hasText: itemName}), isVisible); } - async clickLinkWithName(name: string, isExact: boolean = false) { - await expect(this.page.getByRole('link', {name: name, exact: isExact})).toBeVisible(); - await this.page.getByRole('link', {name: name, exact: isExact}).click(); + async doesMediaHaveThumbnail(mediaId: string, thumbnailIconName: string, thumbnailImage: string) { + const mediaThumbnailLocator = this.page.getByTestId('media:' + mediaId); + if (thumbnailIconName === 'image') { + const regexImageSrc = new RegExp(`^${thumbnailImage}.*`); + await this.hasAttribute(mediaThumbnailLocator.locator('umb-imaging-thumbnail img'), 'src', regexImageSrc.toString()); + } else { + await this.hasAttribute(mediaThumbnailLocator.locator('umb-imaging-thumbnail umb-icon'), 'name', thumbnailIconName); + } } - async clickMediaPickerModalSubmitButton() { - await expect(this.mediaPickerModalSubmitBtn).toBeVisible(); - await this.mediaPickerModalSubmitBtn.click(); + async isInputDropzoneVisible(isVisible: boolean = true) { + await this.isVisible(this.inputDropzone, isVisible); } - async selectMediaWithName(mediaName: string, isForce: boolean = false) { - const mediaLocator = this.mediaCardItems.filter({hasText: mediaName}); - await expect(mediaLocator).toBeVisible(); - await mediaLocator.click({position: {x: 0.5, y: 0.5}, force: isForce}); + async isImageCropperFieldVisible(isVisible: boolean = true) { + await this.isVisible(this.imageCropperField, isVisible); } - async selectMediaWithTestId(mediaKey: string) { - const locator = this.page.getByTestId('media:' + mediaKey); - await expect(locator).toBeVisible(); - await locator.click({position: {x: 0.5, y: 0.5}}); + async isInputUploadFieldVisible(isVisible: boolean = true) { + await this.isVisible(this.inputUploadField, isVisible); } - async clickCreateModalButton() { - await expect(this.createModalBtn).toBeVisible(); - await this.createModalBtn.click(); + // Upload Methods + async clickToUploadButton() { + await this.click(this.clickToUploadBtn); } - async clickMediaCaptionAltTextModalSubmitButton() { - await expect(this.mediaCaptionAltTextModalSubmitBtn).toBeVisible(); - await this.mediaCaptionAltTextModalSubmitBtn.click(); + async uploadFile(filePath: string) { + const [fileChooser] = await Promise.all([ + this.page.waitForEvent('filechooser'), + await this.clickToUploadButton(), + ]); + await fileChooser.setFiles(filePath); } - // Embed Modal + // Embedded Media Methods async enterEmbeddedURL(value: string) { - await expect(this.embeddedURLTxt).toBeVisible(); - await this.embeddedURLTxt.clear(); - await this.embeddedURLTxt.fill(value); + await this.enterText(this.embeddedURLTxt, value); } async clickEmbeddedRetrieveButton() { - await expect(this.embeddedRetrieveBtn).toBeVisible(); - await this.embeddedRetrieveBtn.click(); + await this.click(this.embeddedRetrieveBtn); } async clickEmbeddedMediaModalConfirmButton() { - await expect(this.embeddedMediaModalConfirmBtn).toBeVisible(); - await this.embeddedMediaModalConfirmBtn.click(); + await this.click(this.embeddedMediaModalConfirmBtn); } async waitForEmbeddedPreviewVisible() { - await expect(this.embeddedPreview).toBeVisible(); - } - - async isSubmitButtonDisabled() { - await expect(this.submitBtn).toBeVisible(); - await expect(this.submitBtn).toHaveAttribute('disabled'); + await this.waitForVisible(this.embeddedPreview); } - async doesMediaHaveThumbnail(mediaId: string, thumbnailIconName: string, thumbnailImage: string) { - const mediaThumbnailLocator = this.page.getByTestId('media:' + mediaId); - if (thumbnailIconName === 'image') { - const regexImageSrc = new RegExp(`^${thumbnailImage}.*`); - await expect(mediaThumbnailLocator.locator('umb-imaging-thumbnail img')).toHaveAttribute('src', regexImageSrc); - } else { - await expect(mediaThumbnailLocator.locator('umb-imaging-thumbnail umb-icon')).toHaveAttribute('name', thumbnailIconName); - } + // Document Methods + async clickChooseContentStartNodeButton() { + await this.click(this.chooseDocumentInputBtn); } + // User Methods async clickCurrentUserAvatarButton() { - await expect(this.currentUserAvatarBtn).toBeVisible(); - await this.currentUserAvatarBtn.click({force: true}); + await this.click(this.currentUserAvatarBtn, {force: true}); } + // Collection Methods async clickCreateActionButton() { - await expect(this.createActionBtn).toBeVisible(); - await this.createActionBtn.click(); + await this.click(this.createActionBtn); } async clickCreateActionWithOptionName(optionName: string) { await this.clickCreateActionButton(); const createOptionLocator = this.createActionButtonCollection.locator('[label="' + optionName + '"]'); - await expect(createOptionLocator).toBeVisible(); - await createOptionLocator.click(); + await this.click(createOptionLocator); } async doesCollectionTreeItemTableRowHaveName(name: string) { - await expect(this.collectionTreeItemTableRow.first()).toBeVisible(); - await expect(this.collectionTreeItemTableRow.locator('[label="' + name + '"]')).toBeVisible(); + await this.waitForVisible(this.collectionTreeItemTableRow.first()); + await this.isVisible(this.collectionTreeItemTableRow.locator('[label="' + name + '"]')); } async doesCollectionTreeItemTableRowHaveIcon(name: string, icon: string) { - await expect(this.collectionTreeItemTableRow.first()).toBeVisible(); - await expect(this.collectionTreeItemTableRow.filter({hasText: name}).locator('umb-icon').locator('[name="' + icon + '"]')).toBeVisible(); + await this.waitForVisible(this.collectionTreeItemTableRow.first()); + await this.isVisible(this.collectionTreeItemTableRow.filter({hasText: name}).locator('umb-icon').locator('[name="' + icon + '"]')); } - async clickFolderButton() { - await expect(this.folderBtn).toBeVisible(); - await this.folderBtn.click(); + // Reference Methods + async clickReferenceNodeLinkWithName(name: string) { + await this.click(this.page.locator('[name="' + name + '"] a#open-part')); } async doesReferenceHeadlineHaveText(text: string) { - await expect(this.referenceHeadline).toContainText(text); + await this.containsText(this.referenceHeadline, text); } async isReferenceHeadlineVisible(isVisible: boolean) { - await expect(this.referenceHeadline).toBeVisible({visible: isVisible}); + await this.isVisible(this.referenceHeadline, isVisible); } async doesReferenceItemsHaveCount(count: number) { - await expect(this.entityItemRef).toHaveCount(count); + await this.hasCount(this.entityItemRef, count); } async isReferenceItemNameVisible(itemName: string) { - await expect(this.entityItemRef.locator('uui-ref-node[name="' + itemName + '"]')).toBeVisible(); + await this.isVisible(this.entityItemRef.locator('uui-ref-node[name="' + itemName + '"]')); } async doesReferencesContainText(text: string) { - await expect(this.confirmActionModalEntityReferences).toContainText(text); - } - - async isValidationMessageVisible(message: string, isVisible: boolean = true) { - await expect(this.validationMessage.filter({hasText: message})).toBeVisible({visible: isVisible}); - } - - async isSuccessStateIconVisible() { - await expect(this.successStateIcon).toBeVisible(); - } - - async isPropertyEditorUiWithNameReadOnly(name: string) { - const propertyEditorUiLocator = this.page.locator('umb-property-editor-ui-' + name); - await expect(propertyEditorUiLocator).toHaveAttribute('readonly'); + await this.containsText(this.confirmActionModalEntityReferences, text); } - async isPropertyEditorUiWithNameVisible(name: string, isVisible: boolean = true) { - const propertyEditorUiLocator = this.page.locator('umb-property-editor-ui-' + name); - await expect(propertyEditorUiLocator).toBeVisible({visible: isVisible}); - } - - // Entity Action + // Entity Action Methods async clickEntityActionWithName(name: string) { const regex = new RegExp(`^entity-action:.*${name}$`); - await this.openEntityAction.getByTestId(regex).filter({has: this.page.locator(':visible')}).click(); + await this.click(this.openEntityAction.getByTestId(regex).filter({has: this.page.locator(':visible')})); } async clickCreateActionMenuOption() { @@ -1419,85 +1451,76 @@ export class UiBaseLocators { await this.clickEntityActionWithName('Update'); } - async clickModalMenuItemWithName(name: string) { - await expect(this.openedModal.locator('uui-menu-item[label="' + name + '"]')).toBeVisible(); - await this.openedModal.locator('uui-menu-item[label="' + name + '"]').click(); - } - - async isModalMenuItemWithNameDisabled(name: string) { - await expect(this.sidebarModal.locator('uui-menu-item[label="' + name + '"]')).toHaveAttribute('disabled'); - } - - async doesPropertyHaveInvalidBadge(propertyName: string) { - await expect(this.page.locator('umb-property-layout').filter({hasText: propertyName}).locator('#invalid-badge uui-badge')).toBeVisible(); - } - - async isModalMenuItemWithNameVisible(name: string, isVisible: boolean = true) { - await expect(this.sidebarModal.locator('uui-menu-item[label="' + name + '"]')).toBeVisible({visible: isVisible}); + async clickLockActionMenuOption() { + await this.clickEntityActionWithName('Lock'); } + // Entity Item Methods async clickEntityItemByName(itemName: string) { - await expect(this.page.locator('uui-ref-node,umb-ref-item[name="' + itemName + '"]')).toBeVisible(); - await this.page.locator('uui-ref-node,umb-ref-item[name="' + itemName + '"]').click(); + await this.click(this.page.locator('uui-ref-node,umb-ref-item[name="' + itemName + '"]')); } - async isMediaCardItemWithNameDisabled(itemName: string) { - await expect(this.mediaCardItems.filter({hasText: itemName})).toHaveAttribute('class', 'not-allowed'); + // Workspace Action Methods + async clickWorkspaceActionMenuButton() { + await this.click(this.workspaceActionMenuBtn); } - async isMediaCardItemWithNameVisible(itemName: string, isVisible: boolean = true) { - await expect(this.mediaCardItems.filter({hasText: itemName})).toBeVisible({visible: isVisible}); + // Pagination Methods + async clickNextPaginationButton() { + await this.click(this.nextPaginationBtn); } - async clickWorkspaceActionMenuButton() { - await expect(this.workspaceActionMenuBtn).toBeVisible(); - await this.workspaceActionMenuBtn.click(); + // Editor Methods + async enterMonacoEditorValue(value: string) { + await this.click(this.monacoEditor); + await this.pressKey(this.monacoEditor, 'Control+A'); + await this.pressKey(this.monacoEditor, 'Backspace'); + await this.page.keyboard.insertText(value); } - async clickLockActionMenuOption() { - await this.clickEntityActionWithName('Lock'); + // Loader Methods + async waitUntilUiLoaderIsNoLongerVisible() { + await this.waitForHidden(this.uiLoader, 10000); } + // Dashboard Methods async isDashboardTabWithNameVisible(name: string, isVisible: boolean = true) { - await expect(this.page.locator('uui-tab[label="' + name + '"]')).toBeVisible({visible: isVisible}); + await this.isVisible(this.page.locator('uui-tab[label="' + name + '"]'), isVisible); } - async enterMonacoEditorValue(value: string) { - await expect(this.monacoEditor).toBeVisible(); - await this.monacoEditor.click(); - await this.page.keyboard.press('Control+A'); - await this.page.keyboard.press('Backspace'); - await this.page.keyboard.insertText(value); + async isWorkspaceViewTabWithAliasVisible(alias: string, isVisible: boolean = true) { + await this.isVisible(this.page.getByTestId('workspace:view-link:' + alias), isVisible); } - async waitUntilUiLoaderIsNoLongerVisible() { - await expect(this.uiLoader).toBeVisible({visible: false, timeout: 10000}); + // Submit Button Methods + async isSubmitButtonDisabled() { + await this.isVisible(this.submitBtn); + await this.isDisabled(this.submitBtn); } - async isWorkspaceViewTabWithAliasVisible(alias: string, isVisible: boolean = true) { - await expect(this.page.getByTestId('workspace:view-link:' + alias)).toBeVisible({visible: isVisible}); + // Data Element Methods + async clickDataElement(elementName: string, options: any = null) { + await this.click(this.page.locator(`[data-element="${elementName}"]`), options); } - async clickRestoreButton() { - await expect(this.restoreBtn).toBeVisible(); - await this.restoreBtn.click(); + async getDataElement(elementName: string) { + return this.page.locator(`[data-element="${elementName}"]`); } - async isInputDropzoneVisible(isVisible: boolean = true) { - await expect(this.inputDropzone).toBeVisible({visible: isVisible}); + getLocatorWithDataMark(dataMark: string) { + return this.page.getByTestId(dataMark); } - async isImageCropperFieldVisible(isVisible: boolean = true) { - await expect(this.imageCropperField).toBeVisible({visible: isVisible}); + // Text Visibility Methods + async isTextWithExactNameVisible(name: string, isVisible = true) { + return expect(this.page.getByText(name, {exact: true})).toBeVisible({visible: isVisible}); } - async isInputUploadFieldVisible(isVisible: boolean = true) { - await expect(this.inputUploadField).toBeVisible({visible: isVisible}); + async isTextWithMessageVisible(message: string, isVisible: boolean = true) { + return await expect(this.page.getByText(message)).toBeVisible({visible: isVisible}); } - async isBackOfficeMainVisible(isVisible: boolean = true) { - // We need to wait to make sure the page has loaded - await this.page.waitForTimeout(1000); - await expect(this.backOfficeMain).toBeVisible({visible: isVisible}); + getTextLocatorWithName(name: string) { + return this.page.getByText(name, {exact: true}); } } diff --git a/lib/helpers/UserGroupUiHelper.ts b/lib/helpers/UserGroupUiHelper.ts index 5faa46d6..977e9d88 100644 --- a/lib/helpers/UserGroupUiHelper.ts +++ b/lib/helpers/UserGroupUiHelper.ts @@ -1,5 +1,6 @@ import {expect, Locator, Page} from "@playwright/test" import {UiBaseLocators} from "./UiBaseLocators"; +import {ConstantHelper} from "./ConstantHelper"; export class UserGroupUiHelper extends UiBaseLocators { private readonly userGroupsBtn: Locator; @@ -44,59 +45,50 @@ export class UserGroupUiHelper extends UiBaseLocators { } async clickUserGroupsButton() { - await expect(this.userGroupsBtn).toBeVisible(); - await this.userGroupsBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.userGroupsBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async enterUserGroupName(name: string) { - await expect(this.enterAName).toBeVisible(); - await this.enterAName.clear(); - await this.enterAName.fill(name); + await this.enterText(this.enterAName, name); } async addLanguageToUserGroup(languageName: string) { - await expect(this.chooseLanguageBtn).toBeVisible(); - await this.chooseLanguageBtn.click(); + await this.click(this.chooseLanguageBtn); await this.clickLabelWithName(languageName, true); await this.clickSubmitButton(); } async clickAllowAccessToAllLanguages() { - await expect(this.allowAccessToAllLanguagesBtn).toBeVisible(); - await this.allowAccessToAllLanguagesBtn.click(); + await this.click(this.allowAccessToAllLanguagesBtn); } async clickAllowAccessToAllDocuments() { - await expect(this.allowAccessToAllDocumentsBtn).toBeVisible(); - await this.allowAccessToAllDocumentsBtn.click(); + await this.click(this.allowAccessToAllDocumentsBtn); } async clickAllowAccessToAllMedia() { - await expect(this.allowAccessToAllMediaBtn).toBeVisible(); - await this.allowAccessToAllMediaBtn.click(); + await this.click(this.allowAccessToAllMediaBtn); } async waitForUserGroupToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForUserGroupToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForUserGroupToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async clickCreateUserGroupButton() { - await expect(this.userGroupCreateBtn).toBeVisible(); - await this.userGroupCreateBtn.click(); + await this.click(this.userGroupCreateBtn); } async clickRemoveLanguageFromUserGroup(languageName: string) { - await expect(this.entityItem.filter({hasText: languageName}).getByLabel('Remove')).toBeVisible(); - await this.entityItem.filter({hasText: languageName}).getByLabel('Remove').click(); + await this.click(this.entityItem.filter({hasText: languageName}).getByLabel('Remove')); } async isUserGroupWithNameVisible(name: string, isVisible = true) { @@ -104,20 +96,19 @@ export class UserGroupUiHelper extends UiBaseLocators { } async clickUserGroupWithName(name: string) { - await expect(this.page.getByRole('link', {name: name})).toBeVisible(); - await this.page.getByRole('link', {name: name}).click(); - await this.page.waitForTimeout(200); + await this.click(this.page.getByRole('link', {name: name})); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async clickPermissionsByName(permissionName: string[]) { for (let i = 0; i < permissionName.length; i++) { - await this.permissionVerbBtn.getByText(permissionName[i], {exact: true}).click(); + await this.click(this.permissionVerbBtn.getByText(permissionName[i], {exact: true})); } } async clickGranularPermissionsByName(permissionName: string[]) { for (let i = 0; i < permissionName.length; i++) { - await this.granularPermissionsModal.getByText(permissionName[i], {exact: true}).click(); + await this.click(this.granularPermissionsModal.getByText(permissionName[i], {exact: true})); } } @@ -136,8 +127,7 @@ export class UserGroupUiHelper extends UiBaseLocators { } async clickChooseSectionButton() { - await expect(this.chooseSectionBtn).toBeVisible(); - await this.chooseSectionBtn.click(); + await this.click(this.chooseSectionBtn); } async doesUserGroupTableHaveSection(userGroupName: string, sectionName: string, hasSection = true) { @@ -145,25 +135,21 @@ export class UserGroupUiHelper extends UiBaseLocators { } async doesUserGroupContainLanguage(languageName: string, isVisible = true) { - await expect(this.languageInput).toBeVisible(); + await this.waitForVisible(this.languageInput); await expect(this.languageInput.filter({hasText: languageName})).toBeVisible({visible: isVisible}); } async clickRemoveSectionFromUserGroup(sectionName: string) { - await expect(this.section.filter({hasText: sectionName}).getByLabel('Remove')).toBeVisible(); - await this.section.filter({hasText: sectionName}).getByLabel('Remove').click(); + await this.click(this.section.filter({hasText: sectionName}).getByLabel('Remove')); } async clickRemoveContentStartNodeFromUserGroup(contentStartNodeName: string) { - await expect(this.contentStartNode.filter({hasText: contentStartNodeName}).getByLabel('Remove')).toBeVisible(); - await this.contentStartNode.filter({hasText: contentStartNodeName}).getByLabel('Remove').click(); + await this.click(this.contentStartNode.filter({hasText: contentStartNodeName}).getByLabel('Remove')); } async clickRemoveMediaStartNodeFromUserGroup(mediaStartNodeName: string) { - const removeMediaStartNodeWithNameLocator = this.mediaStartNode.filter({hasText: mediaStartNodeName}).getByLabel('Remove'); - await expect(removeMediaStartNodeWithNameLocator).toBeVisible(); // Force click is needed - await removeMediaStartNodeWithNameLocator.click({force: true}); + await this.click(this.mediaStartNode.filter({hasText: mediaStartNodeName}).getByLabel('Remove'), {force: true}); } async doesUserGroupHavePermissionEnabled(permissionName: string[]) { @@ -173,18 +159,15 @@ export class UserGroupUiHelper extends UiBaseLocators { } async clickGranularPermissionWithName(permissionName: string) { - await expect(this.granularPermission.getByText(permissionName)).toBeVisible(); - await this.granularPermission.getByText(permissionName).click(); + await this.click(this.granularPermission.getByText(permissionName)); } async clickAddGranularPermission() { - await expect(this.addGranularPermissionBtn).toBeVisible(); - await this.addGranularPermissionBtn.click(); + await this.click(this.addGranularPermissionBtn); } async clickRemoveGranularPermissionWithName(permissionName: string) { - await expect(this.granularPermission.filter({hasText: permissionName}).getByLabel('Remove')).toBeVisible(); - await this.granularPermission.filter({hasText: permissionName}).getByLabel('Remove').click(); + await this.click(this.granularPermission.filter({hasText: permissionName}).getByLabel('Remove')); } async doesSettingHaveValue(headline: string, settings) { @@ -208,7 +191,7 @@ export class UserGroupUiHelper extends UiBaseLocators { } async doesUserGroupContainSection(section: string) { - return await expect(this.sectionList).toContainText(section); + await this.containsText(this.sectionList, section); } async doesUserGroupHaveSections(sections: string[]) { @@ -218,6 +201,6 @@ export class UserGroupUiHelper extends UiBaseLocators { } async doesUserGroupSectionsHaveCount(count: number) { - return await expect(this.section).toHaveCount(count); + await this.hasCount(this.section, count); } } \ No newline at end of file diff --git a/lib/helpers/UserUiHelper.ts b/lib/helpers/UserUiHelper.ts index ba0fdc53..775c0ca1 100644 --- a/lib/helpers/UserUiHelper.ts +++ b/lib/helpers/UserUiHelper.ts @@ -72,61 +72,59 @@ export class UserUiHelper extends UiBaseLocators { } async clickUsersButton() { - await expect(this.usersBtn).toBeVisible(); - await this.usersBtn.click(); + await this.click(this.usersBtn); } async clickCreateUserButton() { - await this.createUserBtn.click(); - await this.page.waitForTimeout(500); + await this.click(this.createUserBtn); + await this.page.waitForTimeout(ConstantHelper.wait.short); } async enterNameOfTheUser(name: string) { - await this.nameOfTheUserTxt.fill(name); + await this.enterText(this.nameOfTheUserTxt, name); } async enterUserEmail(email: string) { - await this.userEmailTxt.fill(email); + await this.enterText(this.userEmailTxt, email); } async waitForUserToBeCreated() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForUserToBeDeleted() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async waitForUserToBeRenamed() { - await this.page.waitForLoadState(); + await this.waitForLoadState(); } async clickAddUserGroupsButton() { - await this.addUserGroupsBtn.click(); + await this.click(this.addUserGroupsBtn); // This wait is necessary to avoid the click on the user group button to be ignored - await this.page.waitForTimeout(200); + await this.page.waitForTimeout(ConstantHelper.wait.minimal); } async clickChooseUserGroupsButton() { - await this.chooseUserGroupsBtn.click(); + await this.click(this.chooseUserGroupsBtn); } async clickOpenUserGroupsButton() { - await this.openUserGroupsBtn.click(); + await this.click(this.openUserGroupsBtn); } async enterUpdatedNameOfUser(name: string) { - await this.updatedNameOfTheUserTxt.fill(name); + await this.enterText(this.updatedNameOfTheUserTxt, name); } async clickUserWithName(name: string) { const userNameLocator = this.page.locator('#open-part').getByText(name, {exact: true}); - await expect(userNameLocator).toBeVisible(); - await userNameLocator.click(); + await this.click(userNameLocator); } async clickChangePasswordButton() { - await this.changePasswordBtn.click(); + await this.click(this.changePasswordBtn); } async updatePassword(newPassword: string) { @@ -139,15 +137,15 @@ export class UserUiHelper extends UiBaseLocators { } async clickChangePhotoButton() { - await this.changePhotoBtn.click(); + await this.click(this.changePhotoBtn); } async clickRemoveButtonForUserGroupWithName(userGroupName: string) { - await this.page.locator('umb-user-group-ref', {hasText: userGroupName}).locator('[label="Remove"]').click(); + await this.click(this.page.locator('umb-user-group-ref', {hasText: userGroupName}).locator('[label="Remove"]')); } async clickRemovePhotoButton() { - await this.removePhotoBtn.click(); + await this.click(this.removePhotoBtn); } async changePhotoWithFileChooser(filePath: string) { @@ -165,7 +163,7 @@ export class UserUiHelper extends UiBaseLocators { let userCount = 0; while (true) { - await this.page.waitForTimeout(1000); + await this.page.waitForTimeout(ConstantHelper.wait.medium); userCount += await this.userSectionCard.count(); // Check if pagination exists and next button is enabled @@ -183,33 +181,33 @@ export class UserUiHelper extends UiBaseLocators { await this.clickNextPaginationButton(); } - + // If we actually navigated through the pagination, we should go back if (amount > 50) { const firstPage = this.firstPaginationBtn; const isFirstPageEnabled = await firstPage.isEnabled(); if (isFirstPageEnabled) { - await firstPage.click(); + await this.click(firstPage); } - await this.page.waitForTimeout(1000); + await this.page.waitForTimeout(ConstantHelper.wait.medium); } - + return expect(userCount).toBe(amount); } async doesUserSectionContainUserWithText(name: string) { - return await expect(this.userGrid).toContainText(name); + await this.containsText(this.userGrid, name); } async filterByStatusName(statusName: string) { - await this.statusBtn.click(); - await this.page.locator('label').filter({hasText: statusName}).click(); + await this.click(this.statusBtn); + await this.click(this.page.locator('label').filter({hasText: statusName})); } async filterByGroupName(groupName: string) { - await this.groupBtn.click(); - await this.page.locator('label').filter({hasText: groupName}).click(); + await this.click(this.groupBtn); + await this.click(this.page.locator('label').filter({hasText: groupName})); } async isPasswordUpdatedForUserWithId(userId: string) { @@ -220,7 +218,7 @@ export class UserUiHelper extends UiBaseLocators { } async clickChooseContainerButton() { - await this.chooseContainerBtn.click(); + await this.click(this.chooseContainerBtn); } async selectUserLanguage(language: string) { @@ -228,35 +226,34 @@ export class UserUiHelper extends UiBaseLocators { } async clickRemoveButtonForContentNodeWithName(name: string) { - await this.entityItem.filter({has: this.page.locator('[name="' + name + '"]')}).hover(); - await this.entityItem.filter({has: this.page.locator('[name="' + name + '"]')}).getByRole('button', { name: 'Remove' }).click({force: true}); + const entityItemLocator = this.entityItem.filter({has: this.page.locator(`[name="${name}"]`)}); + await this.hoverAndClick(entityItemLocator, entityItemLocator.getByRole('button', {name: 'Remove'}), {force: true}); } async clickRemoveButtonForMediaNodeWithName(name: string) { - await this.mediaInput.locator('[name="' + name + '"]').locator('[label="Remove"]').click(); + await this.click(this.mediaInput.locator(`[name="${name}"]`).locator('[label="Remove"]')); } async clickAllowAccessToAllDocumentsToggle() { - await this.allowAccessToAllDocumentsToggle.click(); + await this.click(this.allowAccessToAllDocumentsToggle); } async clickAllowAccessToAllMediaToggle() { - await this.allowAccessToAllMediaToggle.click(); + await this.click(this.allowAccessToAllMediaToggle); } async isUserDisabledTextVisible() { - return await expect(this.disabledTxt).toBeVisible(); + await this.waitForVisible(this.disabledTxt); } async isUserActiveTextVisible() { - return await expect(this.activeTxt).toBeVisible(); + await this.waitForVisible(this.activeTxt); } async orderByNewestUser() { - await expect(this.orderByBtn).toBeVisible(); // Force click is needed - await this.orderByBtn.click({force: true}); - await this.orderByNewestBtn.click(); + await this.click(this.orderByBtn, {force: true}); + await this.click(this.orderByNewestBtn); } async isUserWithNameTheFirstUserInList(name: string) { @@ -264,15 +261,15 @@ export class UserUiHelper extends UiBaseLocators { } async doesUserHaveAccessToContentNode(name: string) { - return await expect(this.documentStartNode.locator('[name="' + name + '"]')).toBeVisible(); + return await expect(this.documentStartNode.locator(`[name="${name}"]`)).toBeVisible(); } async doesUserHaveAccessToMediaNode(name: string) { - return await expect(this.mediaStartNode.locator('[name="' + name + '"]')).toBeVisible(); + return await expect(this.mediaStartNode.locator(`[name="${name}"]`)).toBeVisible(); } async clickUsersMenu() { - await this.usersMenu.click(); + await this.click(this.usersMenu); } async goToUsers() { @@ -288,14 +285,14 @@ export class UserUiHelper extends UiBaseLocators { } async clickUserButton() { - await this.userBtn.click(); + await this.click(this.userBtn); } - + async isGoToProfileButtonVisible(isVisible: boolean = true) { - await expect(this.goToProfileBtn).toBeVisible({visible: isVisible}); + await this.isVisible(this.goToProfileBtn, isVisible); } async clickAPIUserButton() { - await this.apiUserBtn.click(); + await this.click(this.apiUserBtn); } } \ No newline at end of file diff --git a/lib/helpers/WebhookUiHelper.ts b/lib/helpers/WebhookUiHelper.ts index f46c3d18..0752102b 100644 --- a/lib/helpers/WebhookUiHelper.ts +++ b/lib/helpers/WebhookUiHelper.ts @@ -1,4 +1,4 @@ -import {Page, Locator, expect} from "@playwright/test" +import {Page, Locator} from "@playwright/test" import {UiBaseLocators} from "./UiBaseLocators"; import {ConstantHelper} from "./ConstantHelper"; @@ -41,62 +41,47 @@ export class WebhookUiHelper extends UiBaseLocators { } async clickWebhookCreateButton() { - await expect(this.webhookCreateBtn).toBeVisible(); - await this.webhookCreateBtn.click(); + await this.click(this.webhookCreateBtn); } async enterWebhookName(name: string) { - await expect(this.webhookNameTxt).toBeVisible(); - await this.webhookNameTxt.clear(); - await this.webhookNameTxt.fill(name) + await this.enterText(this.webhookNameTxt, name); } async enterUrl(url: string) { - await expect(this.urlTxt).toBeVisible(); - await this.urlTxt.clear(); - await this.urlTxt.fill(url); + await this.enterText(this.urlTxt, url); } async clickChooseEventButton() { - await expect(this.chooseEventBtn).toBeVisible(); - await this.chooseEventBtn.click(); + await this.click(this.chooseEventBtn); } async clickChooseContentTypeButton() { - await expect(this.chooseContentTypeBtn).toBeVisible(); - await this.chooseContentTypeBtn.click(); + await this.click(this.chooseContentTypeBtn); } async clickEnabledToggleButton() { - await expect(this.enabledToggle).toBeVisible(); - await this.enabledToggle.click(); + await this.click(this.enabledToggle); } async clickAddHeadersButton() { - await expect(this.addHeadersBtn).toBeVisible(); - await this.addHeadersBtn.click(); + await this.click(this.addHeadersBtn); } async enterHeaderName(name: string) { - await expect(this.headerNameTxt).toBeVisible(); - await this.headerNameTxt.clear(); - await this.headerNameTxt.fill(name); + await this.enterText(this.headerNameTxt, name); } async enterHeaderValue(value: string) { - await expect(this.headerValueTxt).toBeVisible(); - await this.headerValueTxt.clear(); - await this.headerValueTxt.fill(value); + await this.enterText(this.headerValueTxt, value); } async clickDeleteWebhookWithName(name: string) { const deleteLocator = this.page.locator('uui-table-row').filter({has: this.page.getByText(name, {exact: true})}).locator(this.deleteWebhookEntityAction); - await expect(deleteLocator).toBeVisible(); - await deleteLocator.click(); + await this.click(deleteLocator); } async clickHeaderRemoveButton() { - await expect(this.headerRemoveBtn).toBeVisible(); - await this.headerRemoveBtn.click(); + await this.click(this.headerRemoveBtn); } } \ No newline at end of file diff --git a/lib/helpers/WelcomeDashboardUiHelper.ts b/lib/helpers/WelcomeDashboardUiHelper.ts index 79238a66..1f4e2caa 100644 --- a/lib/helpers/WelcomeDashboardUiHelper.ts +++ b/lib/helpers/WelcomeDashboardUiHelper.ts @@ -13,7 +13,7 @@ export class WelcomeDashboardUiHelper extends UiBaseLocators { } async clickWelcomeTab() { - await this.welcomeTab.click(); + await this.click(this.welcomeTab); } async doesButtonWithLabelInBoxHaveLink(label: string, boxName: string, link: string) { diff --git a/lib/helpers/differentAppSettingsHelpers/ExternalLoginUiHelpers.ts b/lib/helpers/differentAppSettingsHelpers/ExternalLoginUiHelpers.ts index 89bbcf48..a375cf72 100644 --- a/lib/helpers/differentAppSettingsHelpers/ExternalLoginUiHelpers.ts +++ b/lib/helpers/differentAppSettingsHelpers/ExternalLoginUiHelpers.ts @@ -1,4 +1,4 @@ -import {Page, Locator, expect} from "@playwright/test"; +import {Page, Locator} from "@playwright/test"; import {UiBaseLocators} from "../UiBaseLocators"; export class ExternalLoginUiHelpers extends UiBaseLocators { @@ -16,22 +16,18 @@ export class ExternalLoginUiHelpers extends UiBaseLocators { } async clickSignInWithAzureADB2CButton() { - await expect(this.azureADB2CSignInBtn).toBeVisible(); - await this.azureADB2CSignInBtn.click(); + await this.click(this.azureADB2CSignInBtn); } async enterAzureADB2CEmail(email: string) { - await expect(this.azureADB2CEmailTxt).toBeVisible(); - await this.azureADB2CEmailTxt.fill(email); + await this.enterText(this.azureADB2CEmailTxt, email); } async enterAzureADB2CPassword(password: string) { - await expect(this.azureADB2CPasswordTxt).toBeVisible(); - await this.azureADB2CPasswordTxt.fill(password); + await this.enterText(this.azureADB2CPasswordTxt, password); } async clickSignInButton() { - await expect(this.signInBtn).toBeVisible(); - await this.signInBtn.click(); + await this.click(this.signInBtn); } -} \ No newline at end of file +} diff --git a/lib/helpers/differentAppSettingsHelpers/InstallUiHelper.ts b/lib/helpers/differentAppSettingsHelpers/InstallUiHelper.ts index 22fd9923..500b7192 100644 --- a/lib/helpers/differentAppSettingsHelpers/InstallUiHelper.ts +++ b/lib/helpers/differentAppSettingsHelpers/InstallUiHelper.ts @@ -1,4 +1,4 @@ -import {Page, Locator, expect} from "@playwright/test"; +import {Page, Locator} from "@playwright/test"; import {UiBaseLocators} from "../UiBaseLocators"; export class InstallUiHelper extends UiBaseLocators { @@ -24,30 +24,26 @@ export class InstallUiHelper extends UiBaseLocators { } async enterName(name: string) { - await expect(this.nameTxt).toBeVisible(); - await this.nameTxt.fill(name); + await this.enterText(this.nameTxt, name); } async enterEmail(email: string) { - await expect(this.emailTxt).toBeVisible(); - await this.emailTxt.fill(email); + await this.enterText(this.emailTxt, email); } async enterPassword(password: string) { - await expect(this.passwordTxt).toBeVisible(); - await this.passwordTxt.fill(password); + await this.enterText(this.passwordTxt, password); } async setDatabaseType(databaseType: string) { - await this.databaseTypeInput.selectOption(databaseType); + await this.databaseTypeInput.selectOption(databaseType) } async doesDatabaseHaveType(databaseType: string) { - await expect(this.databaseType).toHaveText(databaseType); + await this.hasText(this.databaseType, databaseType); } async clickInstallButton() { - await expect(this.installBtn).toBeVisible(); - await this.installBtn.click(); + await this.click(this.installBtn); } -} \ No newline at end of file +} diff --git a/lib/helpers/index.ts b/lib/helpers/index.ts index f4938c10..5c676026 100644 --- a/lib/helpers/index.ts +++ b/lib/helpers/index.ts @@ -3,4 +3,5 @@ export {UiHelpers} from './UiHelpers'; export {AliasHelper} from './AliasHelper'; export {test} from './testExtension'; export {ConstantHelper} from './ConstantHelper'; -export {NotificationConstantHelper} from './NotificationConstantHelper'; \ No newline at end of file +export {NotificationConstantHelper} from './NotificationConstantHelper'; +export {BasePage} from './BasePage'; \ No newline at end of file