UNPKG

@uuv/playwright

Version:

A solution to facilitate the writing and execution of E2E tests understandable by any human being using cucumber(BDD) and playwright

335 lines (334 loc) 14.1 kB
"use strict"; /** * Software Name : UUV * * SPDX-License-Identifier: MIT * * This software is distributed under the MIT License, * see the "LICENSE" file for more details * * Authors: NJAKO MOLOM Louis Fredice & SERVICAL Stanley * Software description: Make test writing fast, understandable by any human * understanding English or French. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.TimeoutCookie = exports.SelectedElementCookie = exports.MockCookie = exports.CustomCookie = exports.FILTER_TYPE = exports.COOKIE_VALUE = exports.COOKIE_NAME = void 0; exports.getPageOrElement = getPageOrElement; exports.addCookie = addCookie; exports.getCookie = getCookie; exports.deleteCookieByName = deleteCookieByName; exports.findWithRoleAndName = findWithRoleAndName; exports.withinRoleAndName = withinRoleAndName; exports.notFoundWithRoleAndName = notFoundWithRoleAndName; exports.findWithRoleAndNameAndContent = findWithRoleAndNameAndContent; exports.findWithRoleAndNameFocused = findWithRoleAndNameFocused; exports.findWithRoleAndNameAndChecked = findWithRoleAndNameAndChecked; exports.findWithRoleAndNameAndUnchecked = findWithRoleAndNameAndUnchecked; exports.findWithRoleAndNameAndContentDisabled = findWithRoleAndNameAndContentDisabled; exports.findWithRoleAndNameDisabled = findWithRoleAndNameDisabled; exports.findWithRoleAndNameAndContentEnabled = findWithRoleAndNameAndContentEnabled; exports.findWithRoleAndNameEnabled = findWithRoleAndNameEnabled; exports.showAttributesInLocator = showAttributesInLocator; exports.checkTextContentLocator = checkTextContentLocator; exports.click = click; exports.getTimeout = getTimeout; const test_1 = require("@playwright/test"); const runner_commons_1 = require("@uuv/runner-commons"); var COOKIE_NAME; (function (COOKIE_NAME) { COOKIE_NAME["TIMEOUT"] = "uuv.timeout"; COOKIE_NAME["SELECTED_ELEMENT"] = "uuv.withinFocusedElement"; COOKIE_NAME["MOCK_URL"] = "uuv.mockUrl"; })(COOKIE_NAME || (exports.COOKIE_NAME = COOKIE_NAME = {})); var COOKIE_VALUE; (function (COOKIE_VALUE) { COOKIE_VALUE["NOT_EXIST"] = "notExist"; })(COOKIE_VALUE || (exports.COOKIE_VALUE = COOKIE_VALUE = {})); var FILTER_TYPE; (function (FILTER_TYPE) { FILTER_TYPE["SELECTOR"] = "bySelector"; FILTER_TYPE["ROLE"] = "byRole"; FILTER_TYPE["TEXT"] = "byText"; FILTER_TYPE["ARIA_LABEL"] = "byAriaLabel"; FILTER_TYPE["TEST_ID"] = "byTestId"; FILTER_TYPE["SELECTOR_PARENT"] = "bySelectorParent"; })(FILTER_TYPE || (exports.FILTER_TYPE = FILTER_TYPE = {})); class CustomCookie { name = `${COOKIE_VALUE.NOT_EXIST.toString()}`; value = "[]"; domain = ".github.com"; expires = -1; httpOnly = false; path = "/"; sameSite = "Lax"; secure = false; isValid() { return !this.name.includes(COOKIE_VALUE.NOT_EXIST.toString()); } } exports.CustomCookie = CustomCookie; class MockCookie { name; url; verb; isConsumed = false; constructor(name, url, verb) { this.name = name; this.url = url; this.verb = verb; this.isConsumed = false; } } exports.MockCookie = MockCookie; class SelectedElementCookie { name; value; constructor(name, value) { this.name = name; this.value = value; } } exports.SelectedElementCookie = SelectedElementCookie; class TimeoutCookie { name; value; constructor(name, value) { this.name = name; this.value = value; } } exports.TimeoutCookie = TimeoutCookie; async function getPageOrElement(world) { let pointer = world.page; const cookie = await getCookie(world, COOKIE_NAME.SELECTED_ELEMENT); // console.debug("cookieGetPageOrElement", cookie); if (cookie.isValid()) { const filters = JSON.parse(cookie.value); // console.debug("filters",filters); for (const filter of filters) { switch (filter.name) { case FILTER_TYPE.SELECTOR: pointer = pointer.locator(filter.value); break; case FILTER_TYPE.ARIA_LABEL: pointer = pointer.getByLabel(filter.value, { exact: true }); break; case FILTER_TYPE.ROLE: pointer = pointer.getByRole(filter.value, { exact: true }); break; case FILTER_TYPE.TEST_ID: pointer = pointer.getByTestId(filter.value); break; case FILTER_TYPE.TEXT: pointer = pointer.getByText(filter.value, { exact: true }); break; case FILTER_TYPE.SELECTOR_PARENT: pointer = pointer.locator(filter.value); break; default: break; } // console.debug("locatorGetPageOrElement", pointer, filter) await (0, test_1.expect)(pointer).toHaveCount(1); } } return pointer; } async function addCookie(world, cookieName, newCookie) { // console.debug("value", value) const cookieNameStr = `${cookieName.toString()}_${world.testInfo.testId}`; const cookie = await getCookie(world, cookieName); let cookieValue = JSON.parse(cookie.value); const mockCookie = cookieValue.find((cookie => cookie.name === newCookie.name)); switch (cookieName) { case COOKIE_NAME.MOCK_URL: if (mockCookie) { cookieValue .filter((cookie => cookie.name === newCookie.name)) .map((cookie => cookie.isConsumed = true)); } else { cookieValue = []; cookieValue.push(newCookie); } // console.debug("cookieValueJSON", JSON.stringify(cookieValue)); break; case COOKIE_NAME.SELECTED_ELEMENT: cookieValue.push(newCookie); break; case COOKIE_NAME.TIMEOUT: cookieValue.push(newCookie); break; } await world.context.addCookies([{ name: cookieNameStr, value: JSON.stringify(cookieValue), path: "/", domain: ".github.com" }]); } async function getCookie(world, cookieName) { const cookieNameStr = `${cookieName.toString()}_${world.testInfo.testId}`; const cookies = await world.context.cookies(); if (cookies) { const cookieInContext = cookies.filter(cookie => cookie.name === cookieNameStr)[0]; // console.debug("selector", cookieInContext) if (cookieInContext) { return Object.assign(new CustomCookie(), cookieInContext); } } return new CustomCookie(); } async function deleteCookieByName(world, cookieName) { const cookieToDelete = await getCookie(world, cookieName); await world.context.addCookies([ { ...cookieToDelete, expires: 0, }, ]); } async function findWithRoleAndName(world, role, name, otherRoleOptions = {}) { await findWithRoleAndNameAndContent(world, role, name, undefined, otherRoleOptions); } async function withinRoleAndName(world, role, name) { await findWithRoleAndNameAndContent(world, role, name, undefined); await addCookie(world, COOKIE_NAME.SELECTED_ELEMENT, new SelectedElementCookie(FILTER_TYPE.SELECTOR, `role=${role}[name="${name}"]`)); } async function notFoundWithRoleAndName(world, role, name) { role = encodeURIComponent(role); await getPageOrElement(world).then(async (element) => await (0, test_1.expect)(element.getByRole(role, { name: name, exact: true })).toHaveCount(0, { timeout: await getTimeout(world) })); } async function findWithRoleAndNameAndContent(world, expectedRole, name, expectedTextContent = undefined, otherRoleOptions = {}) { expectedRole = encodeURIComponent(expectedRole); await getPageOrElement(world).then(async (element) => { const byRole = await element.getByRole(expectedRole, { name: name, exact: true, ...otherRoleOptions }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); if (expectedTextContent !== undefined) { await checkTextContentLocator(byRole, expectedTextContent); } await byRole.focus({ timeout: 10000 }); }); } async function findWithRoleAndNameFocused(world, expectedRole, name) { expectedRole = encodeURIComponent(expectedRole); await getPageOrElement(world).then(async (element) => { // console.log("final:",expectedRole,name) const byRole = await element.getByRole(expectedRole, { name: name, exact: true }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); await (0, test_1.expect)(byRole).toBeFocused(); }); } async function findWithRoleAndNameAndChecked(world, expectedRole, name) { expectedRole = encodeURIComponent(expectedRole); await getPageOrElement(world).then(async (element) => { const byRole = await element.getByRole(expectedRole, { name: name, exact: true }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); await (0, test_1.expect)(byRole).toBeChecked(); }); } async function findWithRoleAndNameAndUnchecked(world, expectedRole, name) { expectedRole = encodeURIComponent(expectedRole); await getPageOrElement(world).then(async (element) => { const byRole = await element.getByRole(expectedRole, { name: name, exact: true }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); await (0, test_1.expect)(byRole).not.toBeChecked(); }); } async function findWithRoleAndNameAndContentDisabled(world, expectedRole, name, expectedTextContent) { expectedRole = encodeURIComponent(expectedRole); await getPageOrElement(world).then(async (element) => { const byRole = await element.getByRole(expectedRole, { name: name, exact: true }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); await checkTextContentLocator(byRole, expectedTextContent); await (0, test_1.expect)(byRole).toBeDisabled(); }); } async function findWithRoleAndNameDisabled(world, expectedRole, name) { expectedRole = encodeURIComponent(expectedRole); await getPageOrElement(world).then(async (element) => { const byRole = await element.getByRole(expectedRole, { name: name, exact: true }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); await (0, test_1.expect)(byRole).toBeDisabled(); }); } async function findWithRoleAndNameAndContentEnabled(world, expectedRole, name, expectedTextContent) { expectedRole = encodeURIComponent(expectedRole); await getPageOrElement(world).then(async (element) => { const byRole = element.getByRole(expectedRole, { name: name, exact: true }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); await checkTextContentLocator(byRole, expectedTextContent); await (0, test_1.expect)(byRole).toBeEnabled(); }); } async function findWithRoleAndNameEnabled(world, expectedRole, name) { expectedRole = encodeURIComponent(expectedRole); await getPageOrElement(world).then(async (element) => { const byRole = element.getByRole(expectedRole, { name: name, exact: true }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); await (0, test_1.expect)(byRole).toBeEnabled(); }); } async function showAttributesInLocator(element) { const attributes = await element.evaluateHandle((aElement) => { const attributeNames = aElement.getAttributeNames(); const result = {}; attributeNames.forEach((name) => { result[name] = aElement.getAttribute(name); }); return result; }); console.debug("attributes of ", element, await attributes.jsonValue()); } async function checkTextContentLocator(locator, expectedTextContent) { // await showAttributesInLocator(locator); try { await (0, test_1.expect)(locator).toHaveValue(expectedTextContent); } catch (err) { console.error("No value found for locator: ", locator); try { await (0, test_1.expect)(locator).toHaveAttribute("value", expectedTextContent); } catch (err) { console.error("No attribute value found for locator: ", locator); try { if (expectedTextContent === "true") { await (0, test_1.expect)(locator).toBeChecked(); } else { await (0, test_1.expect)(locator).not.toBeChecked(); } } catch (err) { console.error("Can't verify check for locator: ", locator); try { await (0, test_1.expect)(locator).toHaveText(expectedTextContent); } catch (err) { console.error("No text found for locator: ", locator); throw new Error(`Content '${expectedTextContent}' isn't present in locator '${locator}'`); } } } } } async function click(world, role, name) { await getPageOrElement(world).then(async (element) => { const byRole = element.getByRole(role, { name: name, exact: true }); await (0, test_1.expect)(byRole).toHaveCount(1, { timeout: await getTimeout(world) }); await byRole.click(); await deleteCookieByName(world, COOKIE_NAME.SELECTED_ELEMENT); }); } async function getTimeout(world) { const cookieTimeout = await getCookie(world, COOKIE_NAME.TIMEOUT); if (cookieTimeout?.isValid()) { const timeoutCookies = JSON.parse(cookieTimeout.value); if (timeoutCookies.length > 0) { return timeoutCookies[0].value; } } return runner_commons_1.DEFAULT_TIMEOUT; }