Initial user page e2e tests

This commit is contained in:
Kalle 2022-12-12 22:25:41 +02:00
parent 74f6d28c39
commit 23e78f7033
7 changed files with 87 additions and 6 deletions

View File

@ -2,6 +2,7 @@ import clsx from "clsx";
export function Input({
name,
id,
className,
minLength,
maxLength,
@ -11,10 +12,12 @@ export function Input({
pattern,
list,
"data-cy": dataCy,
"aria-label": ariaLabel,
value,
onChange,
}: {
name?: string;
id?: string;
className?: string;
minLength?: number;
maxLength?: number;
@ -24,6 +27,7 @@ export function Input({
pattern?: string;
list?: string;
"data-cy"?: string;
"aria-label"?: string;
value?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
}) {
@ -32,6 +36,7 @@ export function Input({
{leftAddon ? <div className="input-addon">{leftAddon}</div> : null}
<input
name={name}
id={id}
minLength={minLength}
maxLength={maxLength}
defaultValue={defaultValue}
@ -40,6 +45,7 @@ export function Input({
data-cy={dataCy}
value={value}
onChange={onChange}
aria-label={ariaLabel}
/>
{icon}
</div>

View File

@ -211,6 +211,7 @@ function CustomUrlInput({
<Label htmlFor="customUrl">{t("user:customUrl")}</Label>
<Input
name="customUrl"
id="customUrl"
leftAddon="https://sendou.ink/u/"
maxLength={USER.CUSTOM_URL_MAX_LENGTH}
defaultValue={parentRouteData.customUrl ?? undefined}
@ -235,6 +236,7 @@ function InGameNameInputs({
<Input
className="u-edit__in-game-name-text"
name="inGameNameText"
aria-label="In game name"
maxLength={USER.IN_GAME_NAME_TEXT_MAX_LENGTH}
defaultValue={inGameNameParts?.[0]}
/>
@ -242,6 +244,7 @@ function InGameNameInputs({
<Input
className="u-edit__in-game-name-discriminator"
name="inGameNameDiscriminator"
aria-label="In game name discriminator"
maxLength={USER.IN_GAME_NAME_DISCRIMINATOR_LENGTH}
pattern="[0-9]{4}"
defaultValue={inGameNameParts?.[1]}
@ -265,8 +268,9 @@ function SensSelects({
return (
<div className="stack horizontal md">
<div>
<Label>{t("user:stickSens")}</Label>
<Label htmlFor="stickSens">{t("user:stickSens")}</Label>
<select
id="stickSens"
name="stickSens"
defaultValue={parentRouteData.stickSens ?? undefined}
className="u-edit__sens-select"
@ -281,8 +285,9 @@ function SensSelects({
</div>
<div>
<Label>{t("user:motionSens")}</Label>
<Label htmlFor="motionSens">{t("user:motionSens")}</Label>
<select
id="motionSens"
name="motionSens"
defaultValue={parentRouteData.motionSens ?? undefined}
className="u-edit__sens-select"

View File

@ -37,7 +37,9 @@ export default function UserInfoPage() {
{data.country ? (
<div className="u__country">
<span className="u__country-emoji">{data.country.emoji}</span>{" "}
<span className="u__country-name">{data.country.name}</span>
<span className="u__country-name" data-testid="country">
{data.country.name}
</span>
</div>
) : null}
<div className="u__socials">

View File

@ -18,3 +18,11 @@ export async function navigate({ page, url }: { page: Page; url: string }) {
await page.goto(url);
page.getByTestId("hydrated");
}
export async function seed(page: Page) {
return page.request.post("/seed");
}
export async function impersonate(page: Page, userId = 1) {
return page.request.post(`/auth/impersonate?id=${userId}`);
}

60
e2e/user-page.spec.ts Normal file
View File

@ -0,0 +1,60 @@
import { expect, type Page, test } from "@playwright/test";
import { ADMIN_DISCORD_ID } from "~/constants";
import { impersonate, navigate, seed } from "~/utils/playwright";
import { userPage } from "~/utils/urls";
const goToEditPage = (page: Page) =>
page.getByText("Edit", { exact: true }).click();
const submitEditForm = (page: Page) =>
page.getByText("Save", { exact: true }).click();
test.describe("User page", () => {
test("edits user profile", async ({ page }) => {
await seed(page);
await impersonate(page);
await navigate({
page,
url: userPage({ discordId: ADMIN_DISCORD_ID, customUrl: "sendou" }),
});
const country = page.getByTestId("country");
await expect(country).toHaveText("Finland");
await goToEditPage(page);
await page
.getByRole("textbox", { name: "In game name", exact: true })
.fill("Lean");
await page
.getByRole("textbox", { name: "In game name discriminator" })
.fill("1234");
await page.getByLabel("R-stick sens").selectOption("0");
await page.getByLabel("Motion sens").selectOption("-50");
await page.getByLabel("Country").selectOption("SE");
await page.getByLabel("Bio").type("My awesome bio");
await submitEditForm(page);
await expect(country).toHaveText("Sweden");
await page.getByText("My awesome bio").isVisible();
await page.getByText("Lean#1234").isVisible();
await page.getByText("Stick 0 / Motion -5").isVisible();
});
test("has redirecting custom url", async ({ page }) => {
await seed(page);
await impersonate(page);
await navigate({
page,
url: userPage({ discordId: ADMIN_DISCORD_ID }),
});
// got redirected
await expect(page).toHaveURL(/sendou/);
await goToEditPage(page);
await page.getByLabel("Custom URL").fill("lean");
await submitEditForm(page);
await expect(page).toHaveURL(/lean/);
});
});

View File

@ -29,7 +29,7 @@
"test:unit": "uvu -r tsm -r tsconfig-paths/register -i e2e",
"test:e2e": "npx playwright test",
"checks": "npm run test:unit && npm run lint:styles && npm run lint:ts && npm run prettier:check && npm run typecheck",
"cf": "npm run test:unit && npm run check-translation-jsons && npm run lint:styles -- --fix && npm run lint:ts -- --fix && npm run prettier:write && npm run typecheck"
"cf": "npm run test:unit && npm run check-translation-jsons && npm run lint:styles -- --fix && npm run lint:ts -- --fix && npm run prettier:write && npm run typecheck && npm run test:e2e"
},
"dependencies": {
"@faker-js/faker": "^7.6.0",

View File

@ -27,8 +27,8 @@ const config: PlaywrightTestConfig = {
forbidOnly: !!process.env["CI"],
/* Retry on CI only */
retries: process.env["CI"] ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env["CI"] ? 1 : undefined,
/* Opt out of parallel tests. */
workers: 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "list",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */