Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { test, expect } from "@playwright/test";
import { test, expect } from "@support/shared-page";
import { Common } from "../../../utils/common";
import { UIhelper } from "../../../utils/ui-helper";
import { TestHelper } from "../../../support/pages/adoption-insights";
import { skipIfJobName } from "../../../utils/helper";
import { JOB_NAME_PATTERNS } from "../../../utils/constants";
import type { Page } from "@playwright/test";

/* eslint-disable playwright/no-conditional-in-test */

Expand All @@ -19,29 +20,22 @@ test.describe.serial("Test Adoption Insights", () => {

test.describe
.serial("Test Adoption Insights plugin: load permission policies and conditions from files", () => {
let context;
let page;
let page: Page;
let testHelper: TestHelper;
let uiHelper: UIhelper;
let initialSearchCount: number;
let templatesFirstEntry: string[];
let catalogEntitiesFirstEntry: string[];
let techdocsFirstEntry: string[];

// Shared setup
test.beforeAll(async ({ browser }) => {
context = await browser.newContext();
page = await context.newPage();
test.beforeAll(async ({ sharedPage }) => {
page = sharedPage;
uiHelper = new UIhelper(page);
testHelper = new TestHelper(page);
await new Common(page).loginAsKeycloakUser();
await uiHelper.goToPageUrl("/", "Welcome back!");
});

test.afterAll(async () => {
await context?.close();
});

test("Check UI navigation by nav bar when adoption-insights is enabled", async () => {
await uiHelper.openSidebarButton("Administration");
await uiHelper.clickLink("Adoption Insights");
Expand Down Expand Up @@ -224,6 +218,7 @@ test.describe.serial("Test Adoption Insights", () => {
.locator("table.v5-MuiTable-root tbody tr")
.first();
const firstEntry = firstRow.locator("td").first();
// @ts-expect-error PanelState.firstRow is typed as string[] but reassigned to a Locator — pre-existing issue
state[title].firstRow = firstRow;

let headerTxt: string;
Expand Down
14 changes: 4 additions & 10 deletions e2e-tests/playwright/e2e/plugins/scorecard/scorecard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,15 @@
* limitations under the License.
*/

import { test } from "@playwright/test";
import { test } from "@support/shared-page";
import { Common } from "../../../utils/common";
import { Catalog } from "../../../support/pages/catalog";
// TODO: Re-enable/uncomment once https://issues.redhat.com/browse/RHIDP-12130 is fixed
// import { CatalogImport } from "../../../support/pages/catalog-import";
import { ScorecardPage } from "../../../support/page-objects/scorecard/scorecard-page";
import type { BrowserContext, Page } from "@playwright/test";
import type { Page } from "@playwright/test";

test.describe.serial("Scorecard Plugin Tests", () => {
let context: BrowserContext;
let page: Page;
let catalog: Catalog;
// TODO: Re-enable/uncomment once https://issues.redhat.com/browse/RHIDP-12130 is fixed
Expand All @@ -33,25 +32,20 @@ test.describe.serial("Scorecard Plugin Tests", () => {
let initialGithubCount: number;
let initialJiraCount: number;

test.beforeAll(async ({ browser }, testInfo) => {
test.beforeAll(async ({ sharedPage }, testInfo) => {
testInfo.annotations.push({
type: "component",
description: "scorecard",
});

context = await browser.newContext();
page = await context.newPage();
page = sharedPage;
catalog = new Catalog(page);
// TODO: Re-enable/uncomment once https://issues.redhat.com/browse/RHIDP-12130 is fixed
// catalogImport = new CatalogImport(page);
scorecardPage = new ScorecardPage(page);
await new Common(page).loginAsKeycloakUser();
});

test.afterAll(async () => {
await context?.close();
});

test("Setup aggregated scorecards on homepage", async () => {
await scorecardPage.navigateToHome();

Expand Down
88 changes: 88 additions & 0 deletions e2e-tests/playwright/support/shared-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Worker-scoped fixtures for test.describe.serial() blocks.
// Usage: import { test, expect } from "@support/shared-page";

import {
test as baseTest,
expect as baseExpect,
type BrowserContext,
type Page,
} from "@playwright/test";
import path from "node:path";
import fs from "node:fs";

type TestFixtures = {
_sharedTestHook: void;
};

type WorkerFixtures = {
sharedContext: BrowserContext;
sharedPage: Page;
};

// Each Playwright worker runs in its own process, so this flag is per-worker.
let workerHadFailure = false;

// eslint-disable-next-line @typescript-eslint/naming-convention
export const test = baseTest.extend<TestFixtures, WorkerFixtures>({
sharedContext: [
async ({ browser }, use, workerInfo) => {
const videoDir = path.join(
"test-results",
`shared-worker-${workerInfo.workerIndex}`,
"videos",
);

// Always record — Playwright's recordVideo has no retain-on-failure mode
// for manual contexts, so we record unconditionally and delete on success.
// Tracing is managed automatically by Playwright (trace: "on" in config).
const context = await browser.newContext({
recordVideo: {
dir: videoDir,
size: { width: 1280, height: 720 },
},
});

await use(context);

await context.close();

// Retain-on-failure: delete video files when all tests passed
if (!workerHadFailure && fs.existsSync(videoDir)) {
fs.rmSync(videoDir, { recursive: true, force: true });
}
},
{ scope: "worker" },
],

sharedPage: [
async ({ sharedContext }, use) => {
const page = await sharedContext.newPage();
await use(page);
},
{ scope: "worker" },
],

_sharedTestHook: [
async ({ sharedPage }, use, testInfo) => {
await use();

if (testInfo.status !== "passed" && testInfo.status !== "skipped") {
workerHadFailure = true;
try {
const screenshotPath = testInfo.outputPath("failure.png");
await sharedPage.screenshot({ path: screenshotPath });
await testInfo.attach("screenshot", {
path: screenshotPath,
contentType: "image/png",
});
} catch {
// Page may have crashed — screenshot unavailable
}
}
},
{ auto: true },
],
});

// eslint-disable-next-line @typescript-eslint/naming-convention
export const expect = baseExpect;
6 changes: 5 additions & 1 deletion e2e-tests/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
"module": "ESNext",
"moduleResolution": "node",
"noEmit": true,
"resolveJsonModule": true
"resolveJsonModule": true,
"baseUrl": ".",
"paths": {
"@support/*": ["playwright/support/*"]
}
},
"include": ["**/*.ts"]
}
Loading