@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
JavaScript
;
/**
* 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;
}