8000 Fixing flakiness by avoiding a full page refresh by ahus1 · Pull Request #54789 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Draft
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
9 changes: 3 additions & 6 deletions js/apps/admin-ui/test/events/list.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import { type Page, expect } from "@playwright/test";
import { selectItem, switchOn } from "../utils/form.ts";
import { assertNotificationMessage } from "../utils/masthead.ts";

export async function goToEventsConfig(page: Page) {
await page.getByRole("link", { name: "Event configs" }).click();
}

async function removeLastAlert(page: Page) {
await page.getByTestId("last-alert").locator("button").click();
}

async function turnOnUserEvents(page: Page) {
await page.getByTestId("rs-events-tab").click();
await switchOn(page, "[data-testid='eventsEnabled']");
await page.getByTestId("save-user").click();
await removeLastAlert(page);
await assertNotificationMessage(page, "Successfully saved configuration");
}

async function turnOnAdminEvents(page: Page) {
await page.getByTestId("rs-admin-events-tab").click();
await switchOn(page, "[data-testid='adminEventsEnabled']");
await page.getByTestId("save-admin").click();
await removeLastAlert(page);
await assertNotificationMessage(page, "Successfully saved configuration");
}

export async function enableSaveEvents(page: Page) {
Expand Down
11 changes: 2 additions & 9 deletions js/apps/admin-ui/test/realm-settings/login.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect, type Page } from "@playwright/test";
import { switchToggle } from "../utils/form.ts";
import { assertNotificationMessage } from "../utils/masthead.ts";

export async function goToLoginTab(page: Page) {
await page.getByTestId("rs-login-tab").click();
Expand All @@ -13,17 +14,9 @@ export async function toggleLoginSettingAndExpectSuccess(
await expect(toggle).toBeVisible();
const previousState = await toggle.isChecked();

const previousAlert = page.getByTestId("last-alert");
if (await previousAlert.isVisible()) {
await previousAlert.locator("button").first().click();
await expect(previousAlert).toBeHidden();
}

await switchToggle(page, toggle);
await expect
.poll(async () => await toggle.isChecked(), { timeout: 10_000 })
.toBe(!previousState);
await expect(page.getByTestId("last-alert")).toContainText(
/changed successfully/i,
);
await assertNotificationMessage(page, /changed successfully/i);
}
58 changes: 19 additions & 39 deletions js/apps/admin-ui/test/realm-settings/oid4vci-attributes.spec.ts
8000 8000
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { expect, test } from "@playwright/test";
import { generatePath } from "react-router-dom";
import { toRealmSettings } from "../../src/realm-settings/routes/RealmSettings.tsx";
import { createTestBed } from "../support/testbed.ts";
import adminClient from "../utils/AdminClient.js";
import { SERVER_URL, ROOT_PATH } from "../utils/constants.ts";
import { login } from "../utils/login.js";
import { assertNotificationMessage } from "../utils/masthead.ts";
import { changeTimeUnit, selectItem } from "../utils/form.ts";

test("OID4VCI section is hidden in Tokens tab when verifiable credentials are disabled", async ({
Expand Down Expand Up @@ -79,9 +78,7 @@ test("should render fields and save values with correct attribute keys", async (
await nonceField.fill("60");
await credentialOfferLifespanField.fill("120");
await page.getByTestId("tokens-tab-save").click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

const realmData = await adminClient.getRealm(testBed.realm);
expect(realmData).toBeDefined();
Expand Down Expand Up @@ -112,20 +109,13 @@ test("should persist values after page refresh", async ({ page }) => {
await nonceField.fill("60");
await credentialOfferLifespanField.fill("120");
await page.getByTestId("tokens-tab-save").click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

// Refresh the page
await page.reload();

// Navigate back to realm settings using the same pattern as login
const url = new URL(
generatePath(ROOT_PATH, { realm: testBed.realm }),
SERVER_URL,
);
url.hash = toRealmSettings({ realm: testBed.realm }).pathname!;
await page.goto(url.toString());
// TimeSelector shows the saved values in the largest fitting unit (3600s = 1 hour, 7200s = 2 hours)
await expect(nonceField).toHaveValue("1");
await expect(credentialOfferLifespanField).toHaveValue("2");

// The TimeSelector component converts values based on units, so we need to check the actual saved values
const realmData = await adminClient.getRealm(testBed.realm);
Expand Down Expand Up @@ -181,9 +171,7 @@ test("should validate form fields and save valid values", async ({ page }) => {
await expect(saveButton).toBeEnabled();

await saveButton.click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

// Verify the values were saved correctly
const realmData = await adminClient.getRealm(testBed.realm);
Expand Down Expand Up @@ -289,9 +277,7 @@ test("should save signed metadata, encryption, and batch issuance settings", asy
await batchIssuanceInput.fill("5");

await page.getByTestId("tokens-tab-save").click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

const realmData = await adminClient.getRealm(testBed.realm);
expect(
Expand Down Expand Up @@ -338,9 +324,7 @@ test("should save time-based correlation mitigation settings", async ({
await randomizationWindowInput.fill("3600");

await page.getByTestId("tokens-tab-save").click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

await selectItem(page, strategyField, "Round");

Expand All @@ -350,9 +334,7 @@ test("should save time-based correlation mitigation settings", async ({
await selectItem(page, roundingUnitField, "Minutes");

await page.getByTestId("tokens-tab-save").click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

const realmData = await adminClient.getRealm(testBed.realm);
expect(realmData?.attributes?.["oid4vci.time.claims.strategy"]).toBe("round");
Expand Down Expand Up @@ -385,9 +367,7 @@ test("should save Deflate Compression setting", async ({ page }) => {
await deflateSwitch.click({ force: true });

await page.getByTestId("tokens-tab-save").click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

let realmData = await adminClient.getRealm(testBed.realm);
expect(realmData?.attributes?.["oid4vci.request.zip.algorithms"]).toBe(
Expand All @@ -396,9 +376,7 @@ test("should save Deflate Compression setting", async ({ page }) => {

await deflateSwitch.click({ force: true });
await page.getByTestId("tokens-tab-save").click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

realmData = await adminClient.getRealm(testBed.realm);
expect(realmData?.attributes?.["oid4vci.request.zip.algorithms"]).toBe(
Expand Down Expand Up @@ -426,9 +404,7 @@ test("should save issuer info setting", async ({ page }) => {
await issuerInfoField.fill(issuerInfoJson);

await page.getByTestId("tokens-tab-save").click();
await expect(
page.getByText("Realm successfully updated").first(),
).toBeVisible();
await assertNotificationMessage(page, "Realm successfully updated");

const realmData = await adminClient.getRealm(testBed.realm);
expect(realmData?.attributes?.["oid4vci.issuer_info"]).toBe(issuerInfoJson);
Expand Down Expand Up @@ -456,7 +432,9 @@ test("should reject invalid issuer info JSON", async ({ page }) => {
.getByText("Must be a valid JSON array of issuer_info elements.")
.first(),
).toBeVisible();
await expect(page.getByText("Realm successfully updated")).toHaveCount(0);
await expect(
page.getByTestId("global-alerts").getByText("Realm successfully updated"),
).toHaveCount(0);
});

test("should reject issuer info with malformed elements", async ({ page }) => {
Expand All @@ -481,5 +459,7 @@ test("should reject issuer info with malformed elements", async ({ page }) => {
.getByText("Must be a valid JSON array of issuer_info elements.")
.first(),
).toBeVisible();
await expect(page.getByText("Realm successfully updated")).toHaveCount(0);
await expect(
page.getByTestId("global-alerts").getByText("Realm successfully updated"),
).toHaveCount(0);
});
15 changes: 14 additions & 1 deletion js/apps/admin-ui/test/utils/masthead.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,23 @@ import { expect, Page } from "@playwright/test";

const ALERT_TIMEOUT = 15_000;

export async function assertNotificationMessage(page: Page, message: string) {
export async function assertNotificationMessage(
page: Page,
message: string | RegExp,
) {
const alert = page.getByTestId("last-alert");
await expect(alert).toBeVisible({ timeout: ALERT_TIMEOUT });
await expect(alert).toHaveText(message, { timeout: ALERT_TIMEOUT });
// Close the toast so a later assertion for the same message cannot match this stale one
await alert
.getByRole("button")
.click({ timeout: 1_000 })
.catch(() => {
// The toast may have expired on its own between the assertion and the click
});
await expect(
page.getByTestId("global-alerts").getByText(message, { exact: true }),
).toHaveCount(0, { timeout: ALERT_TIMEOUT });
}

function getActionToggleButton(page: Page) {
Expand Down
Loading
0