Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace hard-coded strings in Playwright tests #4804

Merged
merged 2 commits into from
Aug 27, 2024
Merged
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
2 changes: 1 addition & 1 deletion frontend/src/components/VRadio/VRadio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default defineComponent({
/>
<VSvg
name="radiomark"
class="radiomark absolute start-0 h-5 w-5 text-default opacity-0 transition-opacity"
class="radiomark pointer-events-none absolute start-0 h-5 w-5 text-default opacity-0 transition-opacity"
width="20"
height="20"
/>
Expand Down
8 changes: 4 additions & 4 deletions frontend/test/playwright/e2e/all-results-keyboard.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,21 @@ test.describe("all results grid keyboard accessibility test", () => {
}) => {
await walkToType("audio", page)

await expect(page.locator("[role=alert]")).toBeVisible()
await expect(page.getByRole("alert")).toBeVisible()
})

test("should hide the instructions snackbar when interacted with audio", async ({
page,
}) => {
await walkToType("audio", page)

await expect(page.locator("[role=alert]")).toBeVisible()
await expect(page.getByRole("alert")).toBeVisible()

const focusedResult = await locateFocusedResult(page)
const playButton = await audio.getInactive(focusedResult)
await playButton.click()

await expect(page.locator("[role=alert]")).toBeHidden()
await expect(page.getByRole("alert")).toBeHidden()
})

test("should allow toggling audio playback via play/pause click", async ({
Expand All @@ -94,7 +94,7 @@ test.describe("all results grid keyboard accessibility test", () => {
expect(path).toMatch(/\/search\/?\?q=birds$/)

const pauseButton = await audio.getActive(focusedResult)
pauseButton.click()
await pauseButton.click()
await expect(playButton).toBeVisible()
})

Expand Down
6 changes: 3 additions & 3 deletions frontend/test/playwright/e2e/audio-detail.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ const goToCustomAudioPage = async (page: Page) => {
}

const errorPageHeading = (page: Page) => {
return getH1(page, /The content you’re looking for seems to have disappeared/)
return getH1(page, t("404.title"))
}
const getMainPlayButton = (page: Page) =>
page.getByRole("button", { name: "Play" }).first()
page.getByRole("button", { name: t("playPause.play") }).first()

test.describe.configure({ mode: "parallel" })

Expand All @@ -46,7 +46,7 @@ test("sends GET_MEDIA event on CTA button click", async ({ context, page }) => {

await goToCustomAudioPage(page)
await openAndCloseExternalLink(page, {
name: new RegExp(t("audioDetails.weblink"), "i"),
name: t("audioDetails.weblink"),
})

const getMediaEvent = analyticsEvents.find((event) => event.n === "GET_MEDIA")
Expand Down
6 changes: 3 additions & 3 deletions frontend/test/playwright/e2e/audio-results.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ test.describe("all results grid keyboard accessibility test", () => {
}) => {
await walkToType("audio", page)

await expect(page.locator("[role=alert]")).toBeVisible()
await expect(page.getByRole("alert")).toBeVisible()
})

test("should hide the instructions snackbar when interacted with audio", async ({
page,
}) => {
await walkToType("audio", page)

await expect(page.locator("[role=alert]")).toBeVisible()
await expect(page.getByRole("alert")).toBeVisible()

const focusedResult = await locateFocusedResult(page)

await focusedResult.press("Space")

await expect(page.locator("[role=alert]")).toBeHidden()
await expect(page.getByRole("alert")).toBeHidden()
})
})
62 changes: 34 additions & 28 deletions frontend/test/playwright/e2e/filters.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {
expectEventPayloadToMatch,
} from "~~/test/playwright/utils/analytics"

import { t } from "~~/test/playwright/utils/i18n"

import enMessages from "~/locales/en.json"

import {
Expand All @@ -34,13 +36,15 @@ const assertCheckboxCount = async (
checked: "checked" | "notChecked" | "total",
count: number
) => {
const checkedString = {
checked: ":checked",
notChecked: ":not(:checked)",
total: "",
}[checked]
const locatorString = `input[type="checkbox"]${checkedString}`
await expect(page.locator(locatorString)).toHaveCount(count, { timeout: 200 })
const options =
checked === "checked"
? { checked: true }
: checked === "notChecked"
? { checked: false }
: {}
await expect(page.getByRole("checkbox", options)).toHaveCount(count, {
timeout: 200,
})
}

// Note that this includes two switches for sensitive content preferences.
Expand All @@ -50,6 +54,14 @@ const FILTER_COUNTS = {
[IMAGE]: 73,
}

const cc0 = t("licenseReadableNames.cc0")

const cc0AndCommercial = [cc0, t("filters.licenseTypes.commercial")]

const commercial = t("filters.licenseTypes.commercial")

const tall = t("filters.aspectRatios.tall")

breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
test.beforeEach(async ({ context, page }) => {
await mockProviderApis(context)
Expand All @@ -72,10 +84,8 @@ breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
test("initial filters are applied based on the url", async ({ page }) => {
await page.goto("/search?q=cat&license_type=commercial&license=cc0")
await filters.open(page)
// Creator filter was removed from the UI
const expectedFilters = ["Zero", "Use commercially"]

for (const checkbox of expectedFilters) {
for (const checkbox of cc0AndCommercial) {
await expect(page.getByRole("checkbox", { name: checkbox })).toBeChecked()
}
})
Expand All @@ -85,10 +95,8 @@ breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
}) => {
await page.goto("/search/?q=cat&license_type=commercial&license=cc0")
await filters.open(page)
// Creator filter was removed from the UI
const expectedFilters = ["Zero", "Use commercially"]

for (const checkbox of expectedFilters) {
for (const checkbox of cc0AndCommercial) {
await expect(page.getByRole("checkbox", { name: checkbox })).toBeChecked()
}
await changeSearchType(page, IMAGE)
Expand All @@ -97,7 +105,7 @@ breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
"/search/image?q=cat&license_type=commercial&license=cc0"
)
await filters.open(page)
for (const checkbox of expectedFilters) {
for (const checkbox of cc0AndCommercial) {
await expect(page.getByRole("checkbox", { name: checkbox })).toBeChecked()
}
})
Expand All @@ -108,15 +116,14 @@ breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
await page.goto("/search/image?q=cat&license_type=commercial&license=cc0")
await filters.open(page)

// Creator filter was removed from the UI
for (const checkbox of ["Zero", "Use commercially"]) {
for (const checkbox of cc0AndCommercial) {
await expect(page.getByRole("checkbox", { name: checkbox })).toBeChecked()
}

await changeSearchType(page, ALL_MEDIA)

await filters.open(page)
await expect(page.locator('input[type="checkbox"]:checked')).toHaveCount(3)
await expect(page.getByRole("checkbox", { checked: true })).toHaveCount(3)

await expect(page).toHaveURL(
"/search?q=cat&license_type=commercial&license=cc0"
Expand All @@ -143,7 +150,7 @@ breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
await filters.open(page)

await expect(
page.getByRole("checkbox", { name: "Use commercially" })
page.getByRole("checkbox", { name: commercial })
).not.toBeChecked()

// Use commercially is not enabled yet, so commercial licenses are still available
Expand All @@ -158,12 +165,10 @@ breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
}

// Enable the commercial use filter
await page.locator('label:has-text("Use commercially")').click()
await page.getByText(t("filters.licenseTypes.commercial")).click()
await page.waitForURL(/license_type=commercial/)

await expect(
page.getByRole("checkbox", { name: "Use commercially" })
).toBeChecked()
await expect(page.getByRole("checkbox", { name: commercial })).toBeChecked()

// Because we checked "Use commercially", licenses that disallow commercial
// use will be disabled and the rest will still be enabled.
Expand Down Expand Up @@ -201,15 +206,16 @@ breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
await page.goto("/search/image?q=cat&aspect_ratio=tall&license=cc0")
await filters.open(page)

await expect(page.getByRole("checkbox", { name: "Tall" })).toBeChecked()
await expect(page.getByRole("checkbox", { name: "Zero" })).toBeChecked()
for (const name of [tall, cc0]) {
await expect(page.getByRole("checkbox", { name })).toBeChecked()
}

await changeSearchType(page, AUDIO)
await filters.open(page)

// Only CC0 checkbox is checked, and the filter button label is
// '1 Filter' on `xl` or '1' on `lg` screens
await expect(page.getByRole("checkbox", { name: "Zero" })).toBeChecked()
await expect(page.getByRole("checkbox", { name: cc0 })).toBeChecked()

await filters.close(page)
// eslint-disable-next-line playwright/no-conditional-in-test
Expand Down Expand Up @@ -238,17 +244,17 @@ breakpoints.describeMobileAndDesktop(({ breakpoint }) => {
await page.goto("/search/image?q=cat")
await filters.open(page)

await expect(page.getByRole("checkbox", { name: "Zero" })).not.toBeChecked()
await expect(page.getByRole("checkbox", { name: cc0 })).not.toBeChecked()

// Alternative way with a predicate. Note no await.
const responsePromise = page.waitForResponse(
(response) =>
response.url().includes("/images/") && response.status() === 200
)
await page.getByLabel("Zero").click()
await page.getByLabel(cc0).click()
const response = await responsePromise

await expect(page.getByRole("checkbox", { name: "Zero" })).toBeChecked()
await expect(page.getByRole("checkbox", { name: cc0 })).toBeChecked()
// Remove the host url and path because when proxied, the 'http://localhost:49153' is used instead of the
// real API url
expect(response.url()).toContain("?q=cat&license=cc0")
Expand Down
8 changes: 5 additions & 3 deletions frontend/test/playwright/e2e/global-audio.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ test.describe("global audio", () => {
// and confirm is still playing (or loading to play)
const mainPlayerButton = page.locator(".main-track >> button").first()

await expect(mainPlayerButton).toHaveAttribute(
"aria-label",
/(Loading|Pause|Replay)/
const labels = ["loading", "pause", "replay"].map((l) =>
t(`playPause.${l}`)
)
const labelPattern = new RegExp(`(${labels.join("|")})`, "i")

await expect(mainPlayerButton).toHaveAttribute("aria-label", labelPattern)
})

test("track can be closed while playing", async ({ page }) => {
Expand Down
18 changes: 13 additions & 5 deletions frontend/test/playwright/e2e/header-internal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ const closeMenu = async (page: Page, dir: LanguageDirection = "ltr") => {
const isPagesPopoverOpen = async (page: Page) =>
page.locator(".popover-content").isVisible({ timeout: 100 })

const aboutPageTitle = t("about.title")

test.describe.configure({ mode: "parallel" })

test.describe("Header internal", () => {
Expand All @@ -43,18 +45,20 @@ test.describe("Header internal", () => {
await clickMenuButton(page)
expect(await isDialogOpen(page)).toBe(true)
await expect(page.locator(currentPageLink)).toBeVisible()
await expect(page.locator(currentPageLink)).toHaveText("About")
await expect(page.locator(currentPageLink)).toHaveText(
t("navigation.about")
)

await closeMenu(page)
expect(await isDialogOpen(page)).toBe(false)
await expect(await getMenuButton(page)).toBeVisible()
await expect(getMenuButton(page)).toBeVisible()
})

test("the modal locks the scroll on xs breakpoint", async ({ page }) => {
await page.goto("/about")

// Wait for hydration
await expect(await getMenuButton(page)).toBeEnabled()
await expect(getMenuButton(page)).toBeEnabled()
await scrollToBottom(page)

await clickMenuButton(page)
Expand Down Expand Up @@ -85,11 +89,13 @@ test.describe("Header internal", () => {
await clickMenuButton(page)
await page.getByRole("link", { name: t("navigation.about") }).click()
await page.waitForURL("/about")

const pageTitleRegex = new RegExp(aboutPageTitle, "i")
// For some reason during this test the navigation overlay sometimes takes ~5-9 ms
// During that time, the page cannot scroll. We just need to wait for the
// page's title to be visible before going on.
await page
.locator("h1", { hasText: "About" })
.getByRole("heading", { level: 1, name: pageTitleRegex })
.waitFor({ state: "visible" })
await scrollToBottom(page)
const scrollPosition = await page.evaluate(() => window.scrollY)
Expand Down Expand Up @@ -125,7 +131,9 @@ test.describe("Header internal", () => {
await clickMenuButton(page)
expect(await isPagesPopoverOpen(page)).toBe(true)
await expect(page.locator(currentPageLinkInPopover)).toBeVisible()
await expect(page.locator(currentPageLinkInPopover)).toHaveText("About")
await expect(page.locator(currentPageLinkInPopover)).toHaveText(
t("navigation.about")
)

await clickMenuButton(page)
expect(await isPagesPopoverOpen(page)).toBe(false)
Expand Down
5 changes: 2 additions & 3 deletions frontend/test/playwright/e2e/image-detail.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const imageObject = {
id: "e9d97a98-621b-4ec2-bf70-f47a74380452",
provider: "flickr",
}

const goToCustomImagePage = async (page: Page) => {
// Test in a custom image detail page, it should apply the same for any image.
await page.goto(`image/${imageObject.id}`)
Expand All @@ -26,7 +25,7 @@ const goToCustomImagePage = async (page: Page) => {
const errorPageLocator = (page: Page) =>
page.getByRole("heading", {
level: 1,
name: /The content you’re looking for seems to have disappeared/,
name: new RegExp(t("404.title")),
obulat marked this conversation as resolved.
Show resolved Hide resolved
})

test.describe.configure({ mode: "parallel" })
Expand Down Expand Up @@ -77,7 +76,7 @@ test("sends GET_MEDIA event on CTA button click", async ({ context, page }) => {

await goToCustomImagePage(page)

await page.getByRole("link", { name: /get this image/i }).click()
await page.getByRole("link", { name: t("imageDetails.weblink") }).click()

const getMediaEvent = analyticsEvents.find((event) => event.n === "GET_MEDIA")

Expand Down
2 changes: 1 addition & 1 deletion frontend/test/playwright/e2e/preferences.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const getSwitchableInput = async (
name: string,
checked: boolean
) => {
const checkbox = page.locator(`input[type=checkbox]#${name}`).first()
const checkbox = page.getByRole("checkbox", { name }).first()
await expect(checkbox).toBeEnabled()
if (checked) {
await expect(checkbox).toBeChecked()
Expand Down
Loading