From ba1ab5c80950c934bf7585b53820c574e25d5380 Mon Sep 17 00:00:00 2001 From: Maurycy Zarzycki Date: Thu, 30 Nov 2023 07:41:58 +0100 Subject: [PATCH] Added attaching logs for failed PW tests --- tests-pw/common/core/BaseTest.js | 37 +++++++++++++--- tests-pw/common/utils/PageUtils.js | 43 +++++++++++++++++-- tests-pw/global.d.ts | 1 - tests-pw/specs/AutoComplete/TextInput.spec.js | 2 +- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/tests-pw/common/core/BaseTest.js b/tests-pw/common/core/BaseTest.js index ce83f74..e96269c 100644 --- a/tests-pw/common/core/BaseTest.js +++ b/tests-pw/common/core/BaseTest.js @@ -4,6 +4,7 @@ import { EditionSelector } from './EditionSelector'; import { TiddlyWikiUi } from '../ui/TiddlyWikiUi'; import { TiddlerStore } from './TiddlerStore'; import { TiddlyWikiConfig } from './TiddlyWikiConfig'; +import { pageRegisterConsoleLogger } from '../utils/PageUtils'; // -------------------- // NOTES.md#002 @@ -19,18 +20,44 @@ import { TiddlyWikiConfig } from './TiddlyWikiConfig'; /** @type {base.Fixtures} */ export const baseTestFixtures = { - store: async({page}, use) => { + page: async ({ page }, use, testInfo) => { + const getConsoleLogs = pageRegisterConsoleLogger(page); + + await use(page); + + if (testInfo.errors.length > 0) { + await testInfo.attach('Console Logs', { + body: getConsoleLogs().map(messageToString).join('\n\n'), + contentType: 'text/plain', + }); + } + }, + store: async ({ page }, use) => { await use(new TiddlerStore(page)); }, - twConfig: async({page, store}, use) => { + twConfig: async ({ page, store }, use) => { await use(new TiddlyWikiConfig(page, store)); }, - selectEdition: async ({page}, use) => { + selectEdition: async ({ page }, use) => { await use(new EditionSelector(page)); }, - ui: async ({page}, use) => { + ui: async ({ page }, use) => { await use(new TiddlyWikiUi(page)); } }; -export const baseTest = base.test.extend(baseTestFixtures); \ No newline at end of file +/** + * @param {import('../utils/PageUtils').PageConsoleMessage} data + * @returns {string} + */ +function messageToString(data) { + const { pageId, message } = data; + + if (message) { + return ` [${message.type()}] ${message.location().url}#${message.location().lineNumber}:${message.location().columnNumber}\n${message.text()}`; + } else { + return ` Page Opened`; + } +} + +export const baseTest = base.test.extend(baseTestFixtures); diff --git a/tests-pw/common/utils/PageUtils.js b/tests-pw/common/utils/PageUtils.js index fdcd7db..d70070c 100644 --- a/tests-pw/common/utils/PageUtils.js +++ b/tests-pw/common/utils/PageUtils.js @@ -2,17 +2,23 @@ import test from "playwright/test"; +/** + * @typedef {Object} PageConsoleMessage + * @property {number} pageId + * @property {import("@playwright/test").ConsoleMessage} [message] + */ + /** * Calls a function that contains page interactions that should lead to a new page being open. * It then returns the newly opened page. * - * @param {import("playwright/test").Page} page + * @param {import("playwright/test").Page} sourcePage * @param {function():Promise} interactionCallback * @returns {Promise} */ -export async function getNewPage(page, interactionCallback) { +export async function getNewPage(sourcePage, interactionCallback) { return await test.step('Attempting to extract new page that is supposed to open', async () => { - const waitForPagePromise = page.context().waitForEvent('page'); + const waitForPagePromise = sourcePage.context().waitForEvent('page'); await interactionCallback(); @@ -21,4 +27,35 @@ export async function getNewPage(page, interactionCallback) { return newPage; }); +} + +/** + * Calls a function that contains page interactions that should lead to a new page being open. + * It then returns the newly opened page. + * + * @param {import("playwright/test").Page} page + * @returns {() => PageConsoleMessage[]} + */ +export function pageRegisterConsoleLogger(page) { + /** + * @type {PageConsoleMessage[]} + */ + const logs = [{ pageId: 0 }]; + + page.on('console', message => { + logs.push({ pageId: 0, message }); + }); + + let pageCounter = 1; + page.context().on('page', newPage => { + const pageId = pageCounter++; + + logs.push({ pageId }); + + newPage.on('console', message => { + logs.push({ pageId, message }); + }); + }) + + return () => logs; } \ No newline at end of file diff --git a/tests-pw/global.d.ts b/tests-pw/global.d.ts index 135508b..f6d4906 100644 --- a/tests-pw/global.d.ts +++ b/tests-pw/global.d.ts @@ -10,7 +10,6 @@ interface TW_Wiki { deleteTiddler(title: string): void; } - interface TW { Tiddler: typeof TW_Tiddler; wiki: TW_Wiki; diff --git a/tests-pw/specs/AutoComplete/TextInput.spec.js b/tests-pw/specs/AutoComplete/TextInput.spec.js index 3261b57..19a4adb 100644 --- a/tests-pw/specs/AutoComplete/TextInput.spec.js +++ b/tests-pw/specs/AutoComplete/TextInput.spec.js @@ -222,8 +222,8 @@ EditionSelector.getEditions(false).forEach(edition => { await inputSecondary.fill(''); await inputSecondary.pressSequentially('[[1'); - await pageSecondary.pause(); const selectedText = (await autoCompleteSecondary.selectedLink.textContent()).trim(); + await autoCompleteSecondary.selectedLink.click(); await expect(inputPrimary).toHaveValue(`[[${selectedText}]]`); await expect(inputSecondary).toHaveValue(`[[${selectedText}]]`);