Path: blob/main/tests/integration/playwright/src/utils.ts
12922 views
import { expect, Locator, PlaywrightTestOptions } from "@playwright/test";12export const getUrl = (path: string) => {3return `http://127.0.0.1:8080/${path}`;4};56// deno-lint-ignore no-explicit-any7export const ojsVal = async (page: any, name: string) => {8return await page.evaluate(async (name: string) => {9const fieldsExist = (obj, names, timeout = 1000) => {10names = names.slice();11// deno-lint-ignore no-explicit-any12let accept: any, reject: any;13const promise = new Promise((a, r) => {14accept = a;15reject = r;16});17const delay = 100;18if (names.length === 0) {19accept(obj);20return promise;21}22let name = names[0];23function tick() {24if (Object.prototype.hasOwnProperty.call(obj, name)) {25names = names.slice(1);26if (names.length === 0) {27accept(obj);28} else {29obj = obj[name];30name = names[0];31//deno-lint-ignore no-window-prefix32window.setTimeout(tick, delay);33}34} else {35timeout -= delay;36if (timeout < 0) {37reject();38} else {39//deno-lint-ignore no-window-prefix40window.setTimeout(tick, delay);41}42}43}44tick();45return promise;46};4748// deno-lint-ignore no-explicit-any49await fieldsExist(window, ["_ojs", "runtime"]);50// await new Promise((resolve) => setTimeout(resolve, 3000));51// deno-lint-ignore no-explicit-any52await (window as any)._ojs.runtime.finishInterpreting();53// deno-lint-ignore no-explicit-any54const val = await (window as any)._ojs.runtime.value(name);55return val;56}, name);57};5859// deno-lint-ignore no-explicit-any60export const ojsRuns = async (page: any) => {61return await page.evaluate(async () => {62const fieldsExist = (obj, names, timeout = 1000) => {63names = names.slice();64// deno-lint-ignore no-explicit-any65let accept: any, reject: any;66const promise = new Promise((a, r) => {67accept = a;68reject = r;69});70const delay = 100;71if (names.length === 0) {72accept(obj);73return promise;74}75let name = names[0];76function tick() {77if (Object.prototype.hasOwnProperty.call(obj, name)) {78names = names.slice(1);79if (names.length === 0) {80accept(obj);81} else {82obj = obj[name];83name = names[0];84//deno-lint-ignore no-window-prefix85window.setTimeout(tick, delay);86}87} else {88timeout -= delay;89if (timeout < 0) {90reject();91} else {92//deno-lint-ignore no-window-prefix93window.setTimeout(tick, delay);94}95}96}97tick();98return promise;99};100101// deno-lint-ignore no-explicit-any102await fieldsExist(window, ["_ojs", "runtime"]);103// await new Promise((resolve) => setTimeout(resolve, 3000));104// deno-lint-ignore no-explicit-any105await (window as any)._ojs.runtime.finishInterpreting();106return true;107});108};109110export const checkClick = async (page: any, locator: any) => {111let error = false;112page.on("pageerror", (_e) => {113error = true;114});115try {116await locator.click();117} catch (_e) {118error = true;119}120return !error;121};122123export type RGBColor = {124red: number;125green: number;126blue: number;127alpha?: number;128};129130export type HexColor = string;131132export function isRGBColor(color: any): color is RGBColor {133return (134typeof color === 'object' &&135'red' in color &&136'green' in color &&137'blue' in color138);139}140141export function isHexColor(color: any): color is HexColor {142return (143typeof color === 'string' &&144/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/.test(color)145);146}147148export async function checkColor(element, cssProperty, color: RGBColor | HexColor) {149let colorString: string;150// Check if the color is an RGBColor object or a string151if (isRGBColor(color)) {152colorString = color.alpha !== undefined153? `rgba(${color.red}, ${color.green}, ${color.blue}, ${color.alpha})`154: `rgb(${color.red}, ${color.green}, ${color.blue})`;155} else if (isHexColor(color)) {156colorString = color as string;157} else {158throw new Error('Invalid color format. Use either RGBColor or HexColor.');159}160// Check the CSS property161await expect(element).toHaveCSS(cssProperty, colorString);162}163164export function asRGB(red: number, green: number, blue: number, alpha?: number): RGBColor {165return { red, green, blue, alpha };166}167168export function hexToRgb(hex: string): RGBColor {169// Remove the # if present170hex = hex.replace(/^#/, '');171172let r: number, g: number, b: number, a: number | undefined = undefined;173174if (hex.length === 3) {175// Handle shorthand #RGB format176r = parseInt(hex[0] + hex[0], 16);177g = parseInt(hex[1] + hex[1], 16);178b = parseInt(hex[2] + hex[2], 16);179} else if (hex.length === 6) {180// Handle #RRGGBB format181r = parseInt(hex.slice(0, 2), 16);182g = parseInt(hex.slice(2, 4), 16);183b = parseInt(hex.slice(4, 6), 16);184} else if (hex.length === 8) {185// Handle #RRGGBBAA format186r = parseInt(hex.slice(0, 2), 16);187g = parseInt(hex.slice(2, 4), 16);188b = parseInt(hex.slice(4, 6), 16);189a = parseInt(hex.slice(6, 8), 16);190} else {191throw new Error('Invalid hex color format');192}193return (asRGB(r, g, b, a));194}195196export async function getCSSProperty(loc: Locator, variable: string, asNumber = false): Promise<string | number> {197const property = await loc.evaluate((element, variable) =>198window.getComputedStyle(element).getPropertyValue(variable),199variable200);201if (asNumber) {202return parseFloat(property);203} else {204return property;205}206}207208export async function checkCSSproperty(loc1: Locator, loc2: Locator, property: string, asNumber: false | true, checkType: 'identical' | 'similar', factor: number = 1) {209let loc1Property = await getCSSProperty(loc1, property, asNumber);210let loc2Property = await getCSSProperty(loc2, property, asNumber);211if (checkType === 'identical') {212await expect(loc2).toHaveCSS(property, loc1Property as string);213} else {214await expect(loc1Property).toBeCloseTo(loc2Property as number * factor);215}216}217218export async function checkFontSizeIdentical(loc1: Locator, loc2: Locator) {219await checkCSSproperty(loc1, loc2, 'font-size', false, 'identical');220}221222export async function checkFontSizeSimilar(loc1: Locator, loc2: Locator, factor: number = 1) {223await checkCSSproperty(loc1, loc2, 'font-size', true, 'similar', factor);224}225226export async function checkColorIdentical(loc1: Locator, loc2: Locator, property: string) {227await checkCSSproperty(loc1, loc2, property, false, 'identical');228}229230export async function checkBorderProperties(element: Locator, side: string, color: RGBColor, width: string) {231await checkColor(element, `border-${side}-color`, color);232await expect(element).toHaveCSS(`border-${side}-width`, width);233}234235export async function checkBackgroundColorProperty(element: Locator, color: RGBColor) {236await checkColor(element, `background-color`, color);237}238239export function useDarkLightMode(mode: 'dark' | 'light'): Partial<PlaywrightTestOptions> {240return {241colorScheme: mode242};243}244245