Skip to content
Open
1 change: 1 addition & 0 deletions e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"showcase-upgrade-nightly": "playwright test --project=showcase-upgrade",
"showcase-auth-providers": "playwright test --project=showcase-auth-providers",
"showcase-sanity-plugins": "playwright test --project=showcase-sanity-plugins",
"showcase-localization-fr": "LOCALE=fr playwright test --project=showcase-localization-fr",
"lint:check": "eslint . --ext .js,.ts",
"lint:fix": "eslint . \"playwright/**/*.{ts,js}\" --fix",
"postinstall": "playwright install chromium",
Expand Down
23 changes: 23 additions & 0 deletions e2e-tests/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import { defineConfig, devices } from "@playwright/test";
process.env.JOB_NAME = process.env.JOB_NAME || "";
process.env.IS_OPENSHIFT = process.env.IS_OPENSHIFT || "";

// Set LOCALE based on which project is being run
const args = process.argv;

if (args.some((arg) => arg.includes("showcase-localization-fr"))) {
process.env.LOCALE = "fr";
} else if (!process.env.LOCALE) {
process.env.LOCALE = "en";
}

const k8sSpecificConfig = {
use: {
actionTimeout: 15 * 1000,
Expand Down Expand Up @@ -176,5 +185,19 @@ export default defineConfig({
"**/playwright/e2e/plugins/quick-access-and-tech-radar.spec.ts",
],
},
{
name: "showcase-localization-fr",
use: {
locale: "fr",
},
testMatch: [
"**/playwright/e2e/extensions.spec.ts",
"**/playwright/e2e/default-global-header.spec.ts",
"**/playwright/e2e/catalog-timestamp.spec.ts",
"**/playwright/e2e/custom-theme.spec.ts",
"**/playwright/e2e/plugins/frontend/sidebar.spec.ts",
"**/playwright/e2e/settings.spec.ts",
],
},
],
});
24 changes: 19 additions & 5 deletions e2e-tests/playwright/e2e/catalog-timestamp.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ import { UIhelper } from "../utils/ui-helper";
import { Common, setupBrowser } from "../utils/common";
import { CatalogImport } from "../support/pages/catalog-import";
import { UI_HELPER_ELEMENTS } from "../support/page-objects/global-obj";
import {
getTranslations,
getCurrentLanguage,
} from "../e2e/localization/locale";

const t = getTranslations();
const lang = getCurrentLanguage();

let page: Page;
test.describe("Test timestamp column on Catalog", () => {
Expand Down Expand Up @@ -31,19 +38,26 @@ test.describe("Test timestamp column on Catalog", () => {
});

test.beforeEach(async () => {
await uiHelper.openSidebar("Catalog");
await uiHelper.verifyHeading("My Org Catalog");
await uiHelper.openSidebar(t["rhdh"][lang]["menuItem.catalog"]);
await uiHelper.verifyHeading(
t["catalog"][lang]["indexPage.title"].replace("{{orgName}}", "My Org"),
);
await uiHelper.openCatalogSidebar("Component");
});

test("Import an existing Git repository and verify `Created At` column and value in the Catalog Page", async () => {
await uiHelper.clickButton("Self-service");
await uiHelper.clickButton("Import an existing Git repository");
await uiHelper.clickButton(t["rhdh"][lang]["menuItem.selfService"]);
await uiHelper.clickButton(
t["catalog-import-test"][lang]["buttons.importExistingGitRepository"],
);
await catalogImport.registerExistingComponent(component);
await uiHelper.openCatalogSidebar("Component");
await uiHelper.searchInputPlaceholder("timestamp-test-created");
await uiHelper.verifyText("timestamp-test-created");
await uiHelper.verifyColumnHeading(["Created At"], true);
await uiHelper.verifyColumnHeading(
[t["rhdh"][lang]["app.table.createdAt"]],
true,
);
await uiHelper.verifyRowInTableByUniqueText("timestamp-test-created", [
/^\d{1,2}\/\d{1,2}\/\d{1,4}, \d:\d{1,2}:\d{1,2} (AM|PM)$/g,
]);
Expand Down
21 changes: 18 additions & 3 deletions e2e-tests/playwright/e2e/custom-theme.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ import {
CUSTOM_SIDEBAR_LOGO,
} from "../support/test-data/custom-theme";
import { ThemeConstants } from "../data/theme-constants";
import {
getTranslations,
getCurrentLanguage,
} from "../e2e/localization/locale";

const t = getTranslations();
const lang = getCurrentLanguage();
let page: Page;

test.describe("CustomTheme should be applied", () => {
Expand All @@ -23,7 +30,11 @@ test.describe("CustomTheme should be applied", () => {
themeVerifier = new ThemeVerifier(page);

await common.loginAsGuest();
await page.getByRole("button", { name: "Hide" }).click();
await page
.getByRole("button", {
name: t["plugin.quickstart"][lang]["footer.hide"],
})
.click();
});

test("Verify theme colors are applied and make screenshots", async ({}, testInfo: TestInfo) => {
Expand Down Expand Up @@ -52,14 +63,18 @@ test.describe("CustomTheme should be applied", () => {
});

test("Verify that RHDH CompanyLogo can be customized", async () => {
await themeVerifier.setTheme("Light");
await themeVerifier.setTheme(
t["user-settings"][lang]["themeToggle.names.light"],
);

await expect(page.getByTestId("home-logo")).toHaveAttribute(
"src",
CUSTOM_SIDEBAR_LOGO.LIGHT,
);

await themeVerifier.setTheme("Dark");
await themeVerifier.setTheme(
t["user-settings"][lang]["themeToggle.names.dark"],
);
await expect(page.getByTestId("home-logo")).toHaveAttribute(
"src",
CUSTOM_SIDEBAR_LOGO.DARK,
Expand Down
92 changes: 71 additions & 21 deletions e2e-tests/playwright/e2e/default-global-header.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { expect, test } from "@playwright/test";
import { UIhelper } from "../utils/ui-helper";
import { Common } from "../utils/common";
import {
getTranslations,
getCurrentLanguage,
} from "../e2e/localization/locale";

const t = getTranslations();
const lang = getCurrentLanguage();

test.describe("Default Global Header", () => {
let common: Common;
Expand All @@ -26,12 +33,20 @@ test.describe("Default Global Header", () => {
test("Verify that global header and default header components are visible", async ({
page,
}) => {
await expect(page.locator(`input[placeholder="Search..."]`)).toBeVisible();
await uiHelper.verifyLink({ label: "Self-service" });
await expect(
page.locator(
`input[placeholder="${t["plugin.global-header"][lang]["search.placeholder"]}"]`,
),
).toBeVisible();
await uiHelper.verifyLink({
label: t["rhdh"][lang]["menuItem.selfService"],
});

const globalHeader = page.locator("nav[id='global-header']");
const helpDropdownButton = globalHeader
.locator("button[aria-label='Help']")
.locator(
`button[aria-label='${t["plugin.global-header"][lang]["help.tooltip"]}']`,
)
.or(
globalHeader.locator("button").filter({
has: page.locator("svg[data-testid='HelpOutlineIcon']"),
Expand All @@ -40,18 +55,26 @@ test.describe("Default Global Header", () => {
.first();

await expect(helpDropdownButton).toBeVisible();
await uiHelper.verifyLink({ label: "Notifications" });
await uiHelper.verifyLink({
label: t["plugin.global-header"][lang]["notifications.title"],
});
expect(await uiHelper.isBtnVisible("rhdh-qe-2")).toBeTruthy();
});

test("Verify that search modal and settings button in sidebar are not visible", async () => {
expect(await uiHelper.isBtnVisible("Search")).toBeFalsy();
expect(await uiHelper.isBtnVisible("Settings")).toBeFalsy();
expect(
await uiHelper.isBtnVisible(t["rhdh"][lang]["app.search.title"]),
).toBeFalsy();
expect(
await uiHelper.isBtnVisible(t["user-settings"][lang]["sidebarTitle"]),
).toBeFalsy();
});

test("Verify that clicking on Self-service button opens the Templates page", async () => {
await uiHelper.clickLink({ ariaLabel: "Self-service" });
await uiHelper.verifyHeading("Self-service");
await uiHelper.clickLink({
ariaLabel: t["rhdh"][lang]["menuItem.selfService"],
});
await uiHelper.verifyHeading(t["rhdh"][lang]["menuItem.selfService"]);
});

test("Verify that clicking on Support button in HelpDropdown opens a new tab", async ({
Expand All @@ -61,7 +84,9 @@ test.describe("Default Global Header", () => {
const globalHeader = page.locator("nav[id='global-header']");

const helpDropdownButton = globalHeader
.locator("button[aria-label='Help']")
.locator(
`button[aria-label='${t["plugin.global-header"][lang]["help.tooltip"]}']`,
)
.or(
globalHeader.locator("button").filter({
has: page.locator("svg[data-testid='HelpOutlineIcon']"),
Expand All @@ -72,7 +97,10 @@ test.describe("Default Global Header", () => {
await helpDropdownButton.click();
await page.waitForTimeout(500);

await uiHelper.verifyTextVisible("Support");
await uiHelper.verifyTextVisible(
t["plugin.global-header"][lang]["help.supportTitle"],
true,
);

const [newTab] = await Promise.all([
context.waitForEvent("page"),
Expand All @@ -89,11 +117,21 @@ test.describe("Default Global Header", () => {

test("Verify Profile Dropdown behaves as expected", async ({ page }) => {
await uiHelper.openProfileDropdown();
await uiHelper.verifyLinkVisible("Settings");
await uiHelper.verifyTextVisible("Sign out");
await uiHelper.verifyLinkVisible(
t["user-settings"][lang]["settingsLayout.title"],
);
await uiHelper.verifyTextVisible(
t["plugin.global-header"][lang]["profile.signOut"],
);

await page.getByRole("menuitem", { name: "Settings" }).click();
await uiHelper.verifyHeading("Settings");
await page
.getByRole("menuitem", {
name: t["user-settings"][lang]["settingsLayout.title"],
})
.click();
await uiHelper.verifyHeading(
t["user-settings"][lang]["settingsLayout.title"],
);

await uiHelper.goToMyProfilePage();
await uiHelper.verifyTextInSelector("header > div > p", "user");
Expand All @@ -104,19 +142,25 @@ test.describe("Default Global Header", () => {
);

await uiHelper.openProfileDropdown();
await page.locator(`p`).getByText("Sign out").first().click();
await uiHelper.verifyHeading("Select a sign-in method");
await page
.locator(`p`)
.getByText(t["plugin.global-header"][lang]["profile.signOut"])
.first()
.click();
await uiHelper.verifyHeading(t["rhdh"][lang]["signIn.page.title"]);
});

test("Verify Search bar behaves as expected", async ({ page }) => {
const searchBar = page.locator(`input[placeholder="Search..."]`);
const searchBar = page.locator(
`input[placeholder="${t["plugin.global-header"][lang]["search.placeholder"]}"]`,
);
await searchBar.click();
await searchBar.fill("test query term");
expect(await uiHelper.isBtnVisibleByTitle("Clear")).toBeTruthy();
const dropdownList = page.locator(`ul[role="listbox"]`);
await expect(dropdownList).toBeVisible();
await searchBar.press("Enter");
await uiHelper.verifyHeading("Search");
await uiHelper.verifyHeading(t["rhdh"][lang]["app.search.title"]);
const searchResultPageInput = page.locator(
`input[id="search-bar-text-field"]`,
);
Expand All @@ -130,10 +174,16 @@ test.describe("Default Global Header", () => {
}) => {
const notificationsBadge = page
.locator("#global-header")
.getByRole("link", { name: "Notifications" });
.getByRole("link", {
name: t["plugin.global-header"][lang]["notifications.title"],
});

await uiHelper.clickLink({ ariaLabel: "Notifications" });
await uiHelper.verifyHeading("Notifications");
await uiHelper.clickLink({
ariaLabel: t["plugin.global-header"][lang]["notifications.title"],
});
await uiHelper.verifyHeading(
t["plugin.global-header"][lang]["notifications.title"],
);
await uiHelper.markAllNotificationsAsReadIfVisible();

const postResponse = await request.post(`${baseURL}/api/notifications`, {
Expand Down
Loading
Loading