Skip to content

Commit

Permalink
SWED-2272 add E2E tests topbar (legacy)
Browse files Browse the repository at this point in the history
  • Loading branch information
goldenraphti committed Aug 23, 2023
1 parent cb177aa commit 3f6af7c
Show file tree
Hide file tree
Showing 22 changed files with 303 additions and 0 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
134 changes: 134 additions & 0 deletions src/App/ComponentsDocumentation/components/Topbar/topbar.e2e.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
// @ts-check
const { test, expect } = require("@playwright/test");

test("Topbar page exist", async ({ page }) => {
await page.goto("http://localhost:3000/");
await page
.getByRole("link", {
name: "Components Find all currently available components here",
})
.click();
await expect(page.getByRole("link", { name: "Topbar" })).toHaveCount(
page.viewportSize().width < 991 ? 1 : 2,
);
await page.getByText("call_to_actionTopbararrow_forward").click();
await expect(page).toHaveTitle(/Topbar/);
await expect(
page.getByRole("heading", { name: "Topbar", exact: true, level: 1 }),
).toBeVisible();
});

const topbarTabs = [
{
name: "legacy desktop",
btnText: "Desktop",
desktopTopbar: true,
isModalUnexpandedFullScreen: false,
hasModal: false,
isLegacy: true,
},
{
name: "legacy mobile",
btnText: "Mobile/tablet",
desktopTopbar: false,
isModalUnexpandedFullScreen: false,
hasModal: true,
isLegacy: true,
},
];
let brand;

/**
*
* @param {import("@playwright/test").Page} page Playwright page object
* @param {string} tabBtnText text of the doc preview container tab
*/
const clickDocPreviewTab = async (page, tabBtnText) => {
await page.getByRole("link", { name: tabBtnText, exact: true }).click();
};

test.describe("visual regressions topbar", () => {
test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:3000/components/topbar");

brand = (await page.title()).includes("Swedbank") ? "SwedbankPay" : "PayEx";
});

test(`general UI closed`, async ({ page }) => {
for (const topbarTab of topbarTabs) {
clickDocPreviewTab(page, topbarTab.btnText);

await expect(
page.locator(".component-preview-content > div"),
).toHaveScreenshot(`${brand}-topbar-${topbarTab.name}-closed.png`);
}
});

// for legacy topbar, on mobile we skip since no links are displayed, no nav displayed in topbar, only in modal
test(`hover & active & normal links`, async ({ page }) => {
test.skip((await page.viewportSize().width) < 1200);

for (const topbarTab of topbarTabs.filter((tab) => tab.desktopTopbar)) {
clickDocPreviewTab(page, topbarTab.btnText);

await page.locator("#demo-topbar").getByRole("link").nth(2).hover();
await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).toHaveScreenshot(
`${brand}-topbar-${topbarTab.name}-links-ui-feedbacks.png`,
);
}
});

test(`general UI modal opened`, async ({ page }) => {
for (const topbarTab of topbarTabs.filter((tab) => tab.hasModal)) {
await page.reload();
clickDocPreviewTab(page, topbarTab.btnText);

await page.locator("#demo-topbar").getByLabel("Open menu").click();

const modalContainer = topbarTab.isModalUnexpandedFullScreen
? page.locator("#demo-topbar").getByRole("navigation")
: page.locator(".component-preview-content > div");

await expect(modalContainer).toHaveScreenshot(
`${brand}-topbar-${topbarTab.name}-opened.png`,
);
}
});

test(`only pinned links are visible on non-expanded view`, async ({
page,
}) => {
for (const topbarTab of topbarTabs.filter(
(tab) => tab.desktopTopbar && !tab.isLegacy,
)) {
clickDocPreviewTab(page, topbarTab.btnText);

// screenshot hover & active & normal links
const pinnedLinks = page
.locator("#demo-topbar")
.getByRole("navigation")
.locator("a.pinned");
const pinnedLinksAmount = await pinnedLinks.count();

for (let linkIndex = 0; linkIndex < pinnedLinksAmount; linkIndex++) {
const loopedLink = pinnedLinks.nth(linkIndex);

await expect(loopedLink).toBeVisible();
}

const nonPinnedLinks = page
.locator("#demo-topbar")
.getByRole("navigation")
.locator("a:not(.pinned)");
const nonPinnedLinksAmount = await nonPinnedLinks.count();

for (let linkIndex = 0; linkIndex < nonPinnedLinksAmount; linkIndex++) {
const loopedLink = nonPinnedLinks.nth(linkIndex);

await expect(loopedLink).not.toBeVisible();
}
}
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
169 changes: 169 additions & 0 deletions src/scripts/main/topbar/topbar.e2e.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
// @ts-check
const { test, expect } = require("@playwright/test");

test.describe(`legacy-topbar script behave correctly`, () => {
test(`topbar opens`, async ({ page }) => {
await page.goto("http://localhost:3000/components/topbar");
await page.getByRole("link", { name: "Desktop", exact: true }).click();

const isDesktopViewport = (await page.viewportSize().width) > 1200;

// expect topbar links to be visible on Desktop but NOT on mobile
if (isDesktopViewport) {
await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).toBeVisible();
} else {
await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).not.toBeVisible();
}

// expect, on load, not to have the "topbar-nav-open" class present YET (until we click on open button)
if (isDesktopViewport) {
await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).not.toHaveClass(/topbar-nav-open/);
}

// on desktop, before clicking any btn, all links & buttons present in nav should always be visible
if (isDesktopViewport) {
for (const navLinkOrBtn of await page
.locator("#demo-topbar")
.getByRole("navigation")
.locator(".topbar-link-container")
.locator("a, button")
.all()) {
expect(navLinkOrBtn).toBeVisible();
}
}

// get dimensions of navigation element
let modalBox = isDesktopViewport
? await page.locator("#demo-topbar").getByRole("navigation").boundingBox()
: null;

// on desktop expect nav to be smaller than full screen (on mobile no nav yet, so we don't care)
if (isDesktopViewport) {
await expect(modalBox.width).not.toBe(page.viewportSize().width);
await expect(modalBox.height).not.toBe(page.viewportSize().height);
}

if (isDesktopViewport) {
// expect NO hamburger menu btn on desktop
await expect(
page.locator("#demo-topbar").getByLabel("Open menu"),
).not.toBeVisible();
} else {
// open modal by clicking the open btn - only MOBILE
await page.locator("#demo-topbar").getByLabel("Open menu").click();
// expect nav to be visible for both desktop AND mobile
await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).toBeVisible();
// expect nav to now have CS class "topbar-nav-open" present
await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).toHaveClass(/topbar-nav-open/);

// expect all links and buttons present in nav to be visible
for (const navLinkOrBtn of await page
.locator("#demo-topbar")
.getByRole("navigation")
.locator(".topbar-link-container")
.locator("a, button")
.all()) {
expect(navLinkOrBtn).toBeVisible();
}

// re-calculate modal dimensions
modalBox = await page
.locator("#demo-topbar")
.getByRole("navigation")
.boundingBox();

const topbarDimensions = await page.locator("#demo-topbar").boundingBox();

// modal should have the same width as the header
await expect(modalBox.width).toBe(topbarDimensions.width);
// modal should be greater than 90% of the viewport height
await expect(modalBox.height).toBeGreaterThan(
(await page.viewportSize().height) * 0.8,
);
}
});

const closeModalActions = [
{
actionType: "keyboardPress",
key: "Escape",
},
{
actionType: "click",
locator: ".topbar-nav.topbar-nav-open",
position: "topLeft",
},
{
actionType: "click",
locator: "#demo-topbar",
position: "closeButton",
},
];

// on legacy topbar only MOBILE have a modal to open and close, so we're only testing on mobile viewport
closeModalActions.map((closingAction) => {
test(`topbar closes on ${closingAction.actionType}-${closingAction.position}`, async ({
page,
}) => {
test.skip((await page.viewportSize().width) > 1200);
await page.goto("http://localhost:3000/components/topbar");
await page.getByRole("link", { name: "Desktop", exact: true }).click();

await page.locator("#demo-topbar").getByLabel("Open menu").click();
await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).toHaveClass(/topbar-nav-open/);

const modalBox = await page
.locator("#demo-topbar")
.getByRole("navigation")
.boundingBox();

const topbarDimensions = await page.locator("#demo-topbar").boundingBox();

// modal should have the same width as the header
await expect(modalBox.width).toBe(topbarDimensions.width);
// modal should be greater than 90% of the viewport height
await expect(modalBox.height).toBeGreaterThan(
(await page.viewportSize().height) * 0.8,
);

// closes the modal
if (closingAction.actionType === "keyboardPress") {
await page.keyboard.press(closingAction.key);
} else if (
closingAction.actionType === "click" &&
closingAction.position === "topLeft"
) {
await page
.locator(closingAction.locator)
.click({ position: { x: 0, y: 0 } });
} else if (
closingAction.actionType === "click" &&
closingAction.position === "closeButton"
) {
await page
.locator(closingAction.locator)
.getByRole("button", { name: "Close menu" })
.click();
}

await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).not.toHaveClass(/topbar-nav-open/);
await expect(
page.locator("#demo-topbar").getByRole("navigation"),
).not.toBeVisible();
});
});
});

0 comments on commit 3f6af7c

Please sign in to comment.