Skip to content

Commit

Permalink
Fix error tests
Browse files Browse the repository at this point in the history
  • Loading branch information
obulat committed Jul 17, 2023
1 parent 5d50953 commit 94ace66
Show file tree
Hide file tree
Showing 26 changed files with 137 additions and 113 deletions.
3 changes: 2 additions & 1 deletion frontend/test/playwright/e2e/header-internal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { test, expect, Page } from "@playwright/test"
import {
isDialogOpen,
LanguageDirection,
preparePageForTests,
scrollToBottom,
setBreakpointCookie,
t,
Expand Down Expand Up @@ -34,7 +35,7 @@ test.describe.configure({ mode: "parallel" })
test.describe("Header internal", () => {
breakpoints.describeXs(() => {
test.beforeEach(async ({ page }) => {
await setBreakpointCookie(page, "xs")
await preparePageForTests(page, "xs")
})

test("can open and close the modal on xs breakpoint", async ({ page }) => {
Expand Down
45 changes: 23 additions & 22 deletions frontend/test/playwright/e2e/load-more.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,35 +130,36 @@ test.describe("Load more button", () => {
})
await expect(page.locator(loadMoreButton)).toBeHidden()
})
})
}

/**
* Checks that an analytics event is posted to /api/event and has the correct
* payload for the REACH_RESULT_END event.
*/
test(`Sends a valid REACH_RESULT_END event when user reaches the load more page`, async ({
page,
context,
}) => {
const analyticsEvents = collectAnalyticsEvents(context)
test.describe("Analytics events", () => {
/**
* Checks that an analytics event is posted to /api/event and has the correct
* payload for the REACH_RESULT_END event.
*/
test(`Sends a valid REACH_RESULT_END event when user reaches the load more page`, async ({
page,
context,
}) => {
const analyticsEvents = collectAnalyticsEvents(context)

await goToSearchTerm(page, "cat")
await page.locator(loadMoreButton).scrollIntoViewIfNeeded()
await expect(page.locator(loadMoreButton)).toBeVisible()
await page.goto("/search/?q=cat")

const reachResultEndEvent = analyticsEvents.find(
(event) => event.n === "REACH_RESULT_END"
)
await page.locator(loadMoreButton).scrollIntoViewIfNeeded()
await expect(page.locator(loadMoreButton)).toBeVisible()

expectEventPayloadToMatch(reachResultEndEvent, {
query: "cat",
searchType: "all",
resultPage: 1,
})
const reachResultEndEvent = analyticsEvents.find(
(event) => event.n === "REACH_RESULT_END"
)

expectEventPayloadToMatch(reachResultEndEvent, {
query: "cat",
searchType: "all",
resultPage: 1,
})
})
}

test.describe(`LOAD_MORE_RESULTS analytics event`, () => {
test(`is sent when loading one page of results.`, async ({
page,
context,
Expand Down
12 changes: 10 additions & 2 deletions frontend/test/playwright/utils/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ export const preparePageForTests = async (
page: Page,
breakpoint: Breakpoint
) => {
await dismissBannersUsingCookies(page)
await dismissAllBannersUsingCookies(page)
await closeFiltersUsingCookies(page)
await setBreakpointCookie(page, breakpoint)
}
Expand All @@ -299,7 +299,7 @@ export const goToSearchTerm = async (
const mode = options.mode ?? "SSR"
const query = options.query ? `&${options.query}` : ""

await dismissBannersUsingCookies(page)
await dismissAllBannersUsingCookies(page)
if (mode === "SSR") {
const path = `${searchPath(searchType)}?q=${term}${query}`
await page.goto(pathWithDir(path, dir))
Expand Down Expand Up @@ -359,13 +359,21 @@ export const getLocatorHref = async (locator: Locator) => {
}

export const scrollToBottom = async (page: Page) => {
// On search page, scroll the main page and not the window.
const mainScrollHeight = await page.evaluate(
() => document.getElementById("main-page")?.scrollHeight ?? 0
)
await page.mouse.wheel(0, mainScrollHeight)

await page.evaluate(() => {
window.scrollTo(0, document.body.scrollHeight)
})
}

export const scrollToTop = async (page: Page) => {
await page.evaluate(() => {
// On search page, scroll the main page and not the window.
document.getElementById("main-page")?.scrollTo(0, 0)
window.scrollTo(0, 0)
})
await sleep(200)
Expand Down
25 changes: 25 additions & 0 deletions frontend/test/playwright/utils/viewport.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { Page } from "@playwright/test"

export const setViewportToFullHeight = async (page: Page) => {
// Because of the overflow scroll, we cannot use `fullPage` screenshots.
// Instead, we set the viewport to the full height of the page content.
const viewportHeight = await page.evaluate(() => {
const headerElHeight =
document.querySelector(".header-el")?.clientHeight ?? 0

// Get the height of the children of the "#main-page" element
const mainPageChildren =
document.getElementById("main-page")?.children ?? []
const childHeight = Array.from(mainPageChildren).reduce(
(acc, child) => acc + child.clientHeight,
0
)
return childHeight + headerElHeight
})

const viewportWidth = page.viewportSize()?.width
await page.setViewportSize({
width: viewportWidth ?? 0,
height: viewportHeight + 1,
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ for (const dir of languageDirections) {

await expectSnapshot(
`external-${searchType}-sources-popover-${dir}`,
page.getByRole("dialog")
page.getByRole("dialog"),
{},
{ maxDiffPixelRatio: 0.01 }
)
})
})
Expand Down
91 changes: 52 additions & 39 deletions frontend/test/playwright/visual-regression/pages/errors.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,37 @@ import breakpoints from "~~/test/playwright/utils/breakpoints"
import {
goToSearchTerm,
preparePageForTests,
renderModes,
} from "~~/test/playwright/utils/navigation"

import { setViewportToFullHeight } from "~~/test/playwright/utils/viewport"

import { supportedSearchTypes } from "~/constants/media"

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

// Tapes for simulating server single result errors.
const errorTapes = [
{ errorStatus: 404, imageId: "da5cb478-c093-4d62-b721-cda18797e3fc" },
{ errorStatus: 429, imageId: "da5cb478-c093-4d62-b721-cda18797e3fd" },
{ errorStatus: 500, imageId: "da5cb478-c093-4d62-b721-cda18797e3fe" },
]

for (const { errorStatus, imageId } of errorTapes) {
breakpoints.describeXl(({ breakpoint, expectSnapshot }) => {
const singleResultCSRErrorStatuses = [404, 429, 500]
/**
* SINGLE RESULT PAGE ERRORS
*/
breakpoints.describeXl(({ breakpoint, expectSnapshot }) => {
for (const { errorStatus, imageId } of errorTapes) {
test(`${errorStatus} error on single-result page on SSR`, async ({
page,
}) => {
await preparePageForTests(page, breakpoint)

const path = `/image/${imageId}`

await page.goto(path)
await page.goto(`/image/${imageId}`)
await expectSnapshot(`single-result-error`, page, { fullPage: true })
})

test(`${errorStatus} on single-result page on CSR`, async ({ page }) => {
}
for (const status of singleResultCSRErrorStatuses) {
test(`${status} on single-result page on CSR`, async ({ page }) => {
await page.route(new RegExp(`v1/images/`), (route) => {
// const requestUrl = route.request().url()

// if (requestUrl.includes("/thumb")) {
// return route.continue()
// }
return route.fulfill({
status: errorStatus,
headers: { "Access-Control-Allow-Origin": "*" },
body: JSON.stringify({}),
})
return route.fulfill({ status })
})

await preparePageForTests(page, breakpoint)
Expand All @@ -60,30 +53,50 @@ for (const { errorStatus, imageId } of errorTapes) {

await expectSnapshot("single-result-error-CSR", page, { fullPage: true })
})
}
})

/**
* SEARCH PAGE ERRORS
*
* On SSR, we only test for 500. TODO: add any other errors like the timeout?
* We can't test 404 errors because when there are no results, the server returns
* a 200 response with an empty list as the `results`.
* The server uses a throttle-exempt key, so we can't get 429 errors.
*/
for (const searchType of supportedSearchTypes) {
breakpoints.describeXl(({ breakpoint, expectSnapshot }) => {
test(`500 error on ${searchType} search on SSR`, async ({ page }) => {
await preparePageForTests(page, breakpoint)
await goToSearchTerm(page, `SearchPage500error`, { searchType })
await setViewportToFullHeight(page)
await expectSnapshot(`search-result-${searchType}-500-error-SSR`, page, {
fullPage: true,
})
})
})
}

for (const { errorStatus } of errorTapes) {
const searchCSRErrorStatuses = [429, 500]

for (const errorStatus of searchCSRErrorStatuses) {
for (const searchType of supportedSearchTypes) {
for (const renderMode of renderModes) {
breakpoints.describeXl(({ breakpoint, expectSnapshot }) => {
test.beforeEach(async ({ page }) => {
await preparePageForTests(page, breakpoint)
breakpoints.describeXl(({ breakpoint, expectSnapshot }) => {
test(`${errorStatus} error on ${searchType} search on CSR`, async ({
page,
}) => {
await preparePageForTests(page, breakpoint)
await goToSearchTerm(page, `SearchPage${errorStatus}error`, {
mode: "CSR",
searchType,
})
test(`${errorStatus} error on ${searchType} search on ${renderMode}`, async ({
await setViewportToFullHeight(page)
await expectSnapshot(
`search-result-${searchType}-${errorStatus}-error-CSR`,
page,
}) => {
await goToSearchTerm(page, `SearchPage${errorStatus}error`, {
mode: renderMode,
searchType,
})
await expectSnapshot(
`search-result-${searchType}-${errorStatus}-error-${renderMode}`,
page,
{ fullPage: true }
)
})
{ fullPage: true }
)
})
}
})
}
}
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
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.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
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.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
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.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
setBreakpointCookie,
} from "~~/test/playwright/utils/navigation"
import breakpoints from "~~/test/playwright/utils/breakpoints"
import { setViewportToFullHeight } from "~~/test/playwright/utils/viewport"

import { supportedSearchTypes } from "~/constants/media"

Expand All @@ -26,27 +27,9 @@ for (const searchType of supportedSearchTypes) {

await goToSearchTerm(page, "querywithnoresults", { dir, searchType })

// Because of the overflow scroll, we cannot use `fullPage` screenshots.
// Instead, we set the viewport to the full height of the page content.
const viewportHeight = await page.evaluate(() => {
const headerElHeight =
document.querySelector(".header-el")?.clientHeight ?? 0

// Get the height of the children of the "#main-page" element
const mainPageChildren =
document.getElementById("main-page")?.children ?? []
const childHeight = Array.from(mainPageChildren).reduce(
(acc, child) => acc + child.clientHeight,
0
)
return childHeight + headerElHeight
})

const viewportWidth = page.viewportSize()?.width
await page.setViewportSize({
width: viewportWidth ?? 0,
height: viewportHeight + 1,
})
await setViewportToFullHeight(page)

await page.mouse.move(0, 82)

await expectSnapshot(`no-results-${searchType}-${dir}`, page)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import { test } from "@playwright/test"

import breakpoints from "~~/test/playwright/utils/breakpoints"
import {
closeFiltersUsingCookies,
dismissBannersUsingCookies,
goToSearchTerm,
languageDirections,
openFirstResult,
pathWithDir,
setBreakpointCookie,
preparePageForTests,
} from "~~/test/playwright/utils/navigation"

import { supportedMediaTypes } from "~/constants/media"
Expand All @@ -17,27 +15,22 @@ test.describe.configure({ mode: "parallel" })

for (const mediaType of supportedMediaTypes) {
for (const dir of languageDirections) {
test.describe(`${mediaType} ${dir} single-result page snapshots`, () => {
breakpoints.describeEvery(({ breakpoint, expectSnapshot }) => {
test.beforeEach(async ({ page }) => {
await closeFiltersUsingCookies(page)
await dismissBannersUsingCookies(page)
await setBreakpointCookie(page, breakpoint)

await goToSearchTerm(page, "birds", { dir })
})

test(`from search results`, async ({ page }) => {
// This will include the "Back to results" link.
await openFirstResult(page, mediaType)

await expectSnapshot(
`${mediaType}-${dir}-from-search-results`,
page,
{ fullPage: true },
{ maxDiffPixelRatio: 0.02 }
)
})
breakpoints.describeEvery(({ breakpoint, expectSnapshot }) => {
test(`${mediaType} ${dir} single-result page snapshots from search results`, async ({
page,
}) => {
await preparePageForTests(page, breakpoint)

await goToSearchTerm(page, "birds", { dir })
// This will include the "Back to results" link.
await openFirstResult(page, mediaType)

await expectSnapshot(
`${mediaType}-${dir}-from-search-results`,
page,
{ fullPage: true },
{ maxDiffPixelRatio: 0.02 }
)
})
})
}
Expand All @@ -46,9 +39,7 @@ for (const mediaType of supportedMediaTypes) {
for (const dir of languageDirections) {
breakpoints.describeMobileAndDesktop(({ breakpoint, expectSnapshot }) => {
test(`${dir} full-page report snapshots`, async ({ page }) => {
await dismissBannersUsingCookies(page)
await closeFiltersUsingCookies(page)
await setBreakpointCookie(page, breakpoint)
await preparePageForTests(page, breakpoint)

const IMAGE_ID = "da5cb478-c093-4d62-b721-cda18797e3fb"
const path = pathWithDir(`/image/${IMAGE_ID}/report`, dir)
Expand Down

0 comments on commit 94ace66

Please sign in to comment.