import {Page, Response} from '@playwright/test'; import moment from 'moment'; import {ActionPanelQA} from '../../src/shared/constants'; import {slct} from '../utils'; export interface BasePageProps { page: Page; } const ENTRY_ID_LENGTH = 13; const extractEntryId = (str: string) => { const ENTRY_ID_FORMAT = /^[0-9a-z]{13}$/; const possibleEntryId = str.slice(0, ENTRY_ID_LENGTH); const isEntryId = ENTRY_ID_FORMAT.test(possibleEntryId); if (isEntryId && (str.length === ENTRY_ID_LENGTH || str[ENTRY_ID_LENGTH] === '-')) { return possibleEntryId; } return null; }; export const waitForSuccessfulResponse = async (url: string, page: Page) => { let res: Response; await page .waitForResponse((response) => { res = response; return response?.url().endsWith(url) && response.status() === 200; }) .catch(() => { throw new Error( `No successful response. Response url: ${res?.url()}, status: ${res?.status()}`, ); }); }; export class BasePage { page: Page; constructor({page}: BasePageProps) { this.page = page; } waitForSelector(selector: string) { return this.page.waitForSelector(selector); } async clickActionPanelMoreButton() { await this.page.click(slct(ActionPanelQA.MoreBtn)); } async waitForSuccessfulResponse(url: string) { await waitForSuccessfulResponse(url, this.page); } async getUrlParams() { return await this.page.evaluate(() => { const urlSearchParams = new URLSearchParams(window.location.search); const entries = urlSearchParams.entries(); const result: {key: string; value: string}[] = []; for (const [key, value] of entries) { result.push({key, value}); } return result; }); } getUniqueEntryName(name: string): string { const timestamp = moment(moment.now()).format('DD.MM.YYYY HH:mm:ss.SSS'); return `${name}__${timestamp}_${Math.random().toString(36).slice(2)}`; } getEntryIdFromUrl() { const urlWithoutProtocol = this.page.url().replace(RegExp('https://|http://'), ''); const [_domain, _path, rawEntryId] = urlWithoutProtocol.split('/'); const entryId = rawEntryId || _path; const questionMarkIndex = entryId.indexOf('?'); if (questionMarkIndex !== -1) { return extractEntryId(entryId.slice(0, questionMarkIndex)); } return extractEntryId(entryId); } async checkHttpErrorsDuringAction(action: () => Promise) { // check that the requests are completed successfully before the callback is resolved. const failedRequests: Response[] = []; const onResponse = (response: Response) => { const status = response.status(); if (status >= 400) { failedRequests.push(response); } }; this.page.on('response', onResponse); await action(); this.page.off('response', onResponse); if (failedRequests.length > 0) { const failedUrls = failedRequests.map((r) => `${r.url()} (${r.status()})`); throw new Error(`Failed requests detected: ${failedUrls.join(', ')}`); } } }