feat(e2e): add data-testids to components
This commit is contained in:
parent
389db59b28
commit
cd09843b99
|
@ -4,6 +4,7 @@ type Props = {
|
||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
type?: "button" | "submit" | "reset" | undefined;
|
type?: "button" | "submit" | "reset" | undefined;
|
||||||
|
"data-testid"?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function AccentSubmitButton({
|
export default function AccentSubmitButton({
|
||||||
|
@ -12,6 +13,7 @@ export default function AccentSubmitButton({
|
||||||
loading,
|
loading,
|
||||||
className,
|
className,
|
||||||
type,
|
type,
|
||||||
|
"data-testid": dataTestId,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
|
@ -19,6 +21,7 @@ export default function AccentSubmitButton({
|
||||||
className={`border primary-btn-gradient select-none duration-200 bg-black border-[oklch(var(--p))] hover:border-[#0070b5] rounded-lg text-center px-4 py-2 text-white active:scale-95 tracking-wider w-fit flex justify-center items-center gap-2 ${
|
className={`border primary-btn-gradient select-none duration-200 bg-black border-[oklch(var(--p))] hover:border-[#0070b5] rounded-lg text-center px-4 py-2 text-white active:scale-95 tracking-wider w-fit flex justify-center items-center gap-2 ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
|
data-testid={dataTestId}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (loading !== undefined && !loading && onClick) onClick();
|
if (loading !== undefined && !loading && onClick) onClick();
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -32,8 +32,14 @@ export default function Modal({ toggleModal, className, children }: Props) {
|
||||||
<Drawer.Overlay className="fixed inset-0 bg-black/40" />
|
<Drawer.Overlay className="fixed inset-0 bg-black/40" />
|
||||||
<ClickAwayHandler onClickOutside={() => setDrawerIsOpen(false)}>
|
<ClickAwayHandler onClickOutside={() => setDrawerIsOpen(false)}>
|
||||||
<Drawer.Content className="flex flex-col rounded-t-2xl h-[90%] mt-24 fixed bottom-0 left-0 right-0 z-30">
|
<Drawer.Content className="flex flex-col rounded-t-2xl h-[90%] mt-24 fixed bottom-0 left-0 right-0 z-30">
|
||||||
<div className="p-4 pb-32 bg-base-100 rounded-t-2xl flex-1 border-neutral-content border-t overflow-y-auto">
|
<div
|
||||||
<div className="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-neutral mb-5" />
|
className="p-4 pb-32 bg-base-100 rounded-t-2xl flex-1 border-neutral-content border-t overflow-y-auto"
|
||||||
|
data-testid="mobile-modal-container"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="mx-auto w-12 h-1.5 flex-shrink-0 rounded-full bg-neutral mb-5"
|
||||||
|
data-testid="mobile-modal-slider"
|
||||||
|
/>
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
@ -44,19 +50,28 @@ export default function Modal({ toggleModal, className, children }: Props) {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div className="overflow-y-auto pt-2 sm:py-2 fixed top-0 bottom-0 right-0 left-0 bg-black bg-opacity-10 backdrop-blur-sm flex justify-center items-center fade-in z-40">
|
<div
|
||||||
|
className="overflow-y-auto pt-2 sm:py-2 fixed top-0 bottom-0 right-0 left-0 bg-black bg-opacity-10 backdrop-blur-sm flex justify-center items-center fade-in z-40"
|
||||||
|
data-testid="modal-outer"
|
||||||
|
>
|
||||||
<ClickAwayHandler
|
<ClickAwayHandler
|
||||||
onClickOutside={toggleModal}
|
onClickOutside={toggleModal}
|
||||||
className={`w-full mt-auto sm:m-auto sm:w-11/12 sm:max-w-2xl ${
|
className={`w-full mt-auto sm:m-auto sm:w-11/12 sm:max-w-2xl ${
|
||||||
className || ""
|
className || ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<div className="slide-up mt-auto sm:m-auto relative border-neutral-content rounded-t-2xl sm:rounded-2xl border-t sm:border shadow-2xl p-5 bg-base-100 overflow-y-auto sm:overflow-y-visible">
|
<div
|
||||||
|
className="slide-up mt-auto sm:m-auto relative border-neutral-content rounded-t-2xl sm:rounded-2xl border-t sm:border shadow-2xl p-5 bg-base-100 overflow-y-auto sm:overflow-y-visible"
|
||||||
|
data-testid="modal-container"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
onClick={toggleModal as MouseEventHandler<HTMLDivElement>}
|
onClick={toggleModal as MouseEventHandler<HTMLDivElement>}
|
||||||
className="absolute top-4 right-3 btn btn-sm outline-none btn-circle btn-ghost z-10"
|
className="absolute top-4 right-3 btn btn-sm outline-none btn-circle btn-ghost z-10"
|
||||||
>
|
>
|
||||||
<i className="bi-x text-neutral text-2xl"></i>
|
<i
|
||||||
|
className="bi-x text-neutral text-2xl"
|
||||||
|
data-testid="close-modal-button"
|
||||||
|
></i>
|
||||||
</div>
|
</div>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,6 +9,7 @@ type Props = {
|
||||||
onKeyDown?: KeyboardEventHandler<HTMLInputElement> | undefined;
|
onKeyDown?: KeyboardEventHandler<HTMLInputElement> | undefined;
|
||||||
className?: string;
|
className?: string;
|
||||||
spellCheck?: boolean;
|
spellCheck?: boolean;
|
||||||
|
"data-testid"?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function TextInput({
|
export default function TextInput({
|
||||||
|
@ -20,9 +21,11 @@ export default function TextInput({
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
className,
|
className,
|
||||||
spellCheck,
|
spellCheck,
|
||||||
|
"data-testid": dataTestId,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
return (
|
return (
|
||||||
<input
|
<input
|
||||||
|
data-testid={dataTestId}
|
||||||
spellCheck={spellCheck}
|
spellCheck={spellCheck}
|
||||||
autoFocus={autoFocus}
|
autoFocus={autoFocus}
|
||||||
type={type ? type : "text"}
|
type={type ? type : "text"}
|
||||||
|
|
|
@ -6,13 +6,21 @@ import React, { ReactNode, useEffect } from "react";
|
||||||
interface Props {
|
interface Props {
|
||||||
text?: string;
|
text?: string;
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
|
"data-testid"?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function CenteredForm({ text, children }: Props) {
|
export default function CenteredForm({
|
||||||
|
text,
|
||||||
|
children,
|
||||||
|
"data-testid": dataTestId,
|
||||||
|
}: Props) {
|
||||||
const { settings } = useLocalSettingsStore();
|
const { settings } = useLocalSettingsStore();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="absolute top-0 bottom-0 left-0 right-0 flex justify-center items-center p-5">
|
<div
|
||||||
|
className="absolute top-0 bottom-0 left-0 right-0 flex justify-center items-center p-5"
|
||||||
|
data-testid={dataTestId}
|
||||||
|
>
|
||||||
<div className="m-auto flex flex-col gap-2 w-full">
|
<div className="m-auto flex flex-col gap-2 w-full">
|
||||||
{settings.theme ? (
|
{settings.theme ? (
|
||||||
<Image
|
<Image
|
||||||
|
|
|
@ -38,7 +38,7 @@ export default function MainLayout({ children }: Props) {
|
||||||
<AnnouncementBar toggleAnnouncementBar={toggleAnnouncementBar} />
|
<AnnouncementBar toggleAnnouncementBar={toggleAnnouncementBar} />
|
||||||
) : undefined}
|
) : undefined}
|
||||||
|
|
||||||
<div className="flex">
|
<div className="flex" data-testid="dashboard-wrapper">
|
||||||
<div className="hidden lg:block">
|
<div className="hidden lg:block">
|
||||||
<Sidebar
|
<Sidebar
|
||||||
className={`fixed ${showAnnouncement ? "top-10" : "top-0"}`}
|
className={`fixed ${showAnnouncement ? "top-10" : "top-0"}`}
|
||||||
|
|
|
@ -69,7 +69,7 @@ export default function Login({
|
||||||
function displayLoginCredential() {
|
function displayLoginCredential() {
|
||||||
if (availableLogins.credentialsEnabled === "true") {
|
if (availableLogins.credentialsEnabled === "true") {
|
||||||
return (
|
return (
|
||||||
<>
|
<div data-testid="login-form">
|
||||||
<p className="text-3xl text-black dark:text-white text-center font-extralight">
|
<p className="text-3xl text-black dark:text-white text-center font-extralight">
|
||||||
Enter your credentials
|
Enter your credentials
|
||||||
</p>
|
</p>
|
||||||
|
@ -87,6 +87,7 @@ export default function Login({
|
||||||
placeholder="johnny"
|
placeholder="johnny"
|
||||||
value={form.username}
|
value={form.username}
|
||||||
className="bg-base-100"
|
className="bg-base-100"
|
||||||
|
data-testid="username-input"
|
||||||
onChange={(e) => setForm({ ...form, username: e.target.value })}
|
onChange={(e) => setForm({ ...form, username: e.target.value })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -100,6 +101,7 @@ export default function Login({
|
||||||
placeholder="••••••••••••••"
|
placeholder="••••••••••••••"
|
||||||
value={form.password}
|
value={form.password}
|
||||||
className="bg-base-100"
|
className="bg-base-100"
|
||||||
|
data-testid="password-input"
|
||||||
onChange={(e) => setForm({ ...form, password: e.target.value })}
|
onChange={(e) => setForm({ ...form, password: e.target.value })}
|
||||||
/>
|
/>
|
||||||
{availableLogins.emailEnabled === "true" && (
|
{availableLogins.emailEnabled === "true" && (
|
||||||
|
@ -107,6 +109,7 @@ export default function Login({
|
||||||
<Link
|
<Link
|
||||||
href={"/forgot"}
|
href={"/forgot"}
|
||||||
className="text-gray-500 dark:text-gray-400 font-semibold"
|
className="text-gray-500 dark:text-gray-400 font-semibold"
|
||||||
|
data-testid="forgot-password-link"
|
||||||
>
|
>
|
||||||
Forgot Password?
|
Forgot Password?
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -117,13 +120,14 @@ export default function Login({
|
||||||
type="submit"
|
type="submit"
|
||||||
label="Login"
|
label="Login"
|
||||||
className=" w-full text-center"
|
className=" w-full text-center"
|
||||||
|
data-testid="submit-login-button"
|
||||||
loading={submitLoader}
|
loading={submitLoader}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{availableLogins.buttonAuths.length > 0 ? (
|
{availableLogins.buttonAuths.length > 0 ? (
|
||||||
<div className="divider my-1">OR</div>
|
<div className="divider my-1">OR</div>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,6 +159,7 @@ export default function Login({
|
||||||
<Link
|
<Link
|
||||||
href={"/register"}
|
href={"/register"}
|
||||||
className="block text-black dark:text-white font-semibold"
|
className="block text-black dark:text-white font-semibold"
|
||||||
|
data-testid="register-link"
|
||||||
>
|
>
|
||||||
Sign Up
|
Sign Up
|
||||||
</Link>
|
</Link>
|
||||||
|
|
|
@ -102,6 +102,7 @@ export default function Register() {
|
||||||
} days of Premium Service at no cost!`
|
} days of Premium Service at no cost!`
|
||||||
: "Create a new account"
|
: "Create a new account"
|
||||||
}
|
}
|
||||||
|
data-testid="registration-form"
|
||||||
>
|
>
|
||||||
{process.env.NEXT_PUBLIC_DISABLE_REGISTRATION === "true" ? (
|
{process.env.NEXT_PUBLIC_DISABLE_REGISTRATION === "true" ? (
|
||||||
<div className="p-4 flex flex-col gap-3 justify-between max-w-[30rem] min-w-80 w-full bg-base-200 rounded-2xl shadow-md border border-neutral-content">
|
<div className="p-4 flex flex-col gap-3 justify-between max-w-[30rem] min-w-80 w-full bg-base-200 rounded-2xl shadow-md border border-neutral-content">
|
||||||
|
@ -127,6 +128,7 @@ export default function Register() {
|
||||||
placeholder="Johnny"
|
placeholder="Johnny"
|
||||||
value={form.name}
|
value={form.name}
|
||||||
className="bg-base-100"
|
className="bg-base-100"
|
||||||
|
data-testid="display-name-input"
|
||||||
onChange={(e) => setForm({ ...form, name: e.target.value })}
|
onChange={(e) => setForm({ ...form, name: e.target.value })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -139,6 +141,7 @@ export default function Register() {
|
||||||
placeholder="john"
|
placeholder="john"
|
||||||
value={form.username}
|
value={form.username}
|
||||||
className="bg-base-100"
|
className="bg-base-100"
|
||||||
|
data-testid="username-input"
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setForm({ ...form, username: e.target.value })
|
setForm({ ...form, username: e.target.value })
|
||||||
}
|
}
|
||||||
|
@ -155,6 +158,7 @@ export default function Register() {
|
||||||
placeholder="johnny@example.com"
|
placeholder="johnny@example.com"
|
||||||
value={form.email}
|
value={form.email}
|
||||||
className="bg-base-100"
|
className="bg-base-100"
|
||||||
|
data-testid="email-input"
|
||||||
onChange={(e) => setForm({ ...form, email: e.target.value })}
|
onChange={(e) => setForm({ ...form, email: e.target.value })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -168,6 +172,7 @@ export default function Register() {
|
||||||
placeholder="••••••••••••••"
|
placeholder="••••••••••••••"
|
||||||
value={form.password}
|
value={form.password}
|
||||||
className="bg-base-100"
|
className="bg-base-100"
|
||||||
|
data-testid="password-input"
|
||||||
onChange={(e) => setForm({ ...form, password: e.target.value })}
|
onChange={(e) => setForm({ ...form, password: e.target.value })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -182,6 +187,7 @@ export default function Register() {
|
||||||
placeholder="••••••••••••••"
|
placeholder="••••••••••••••"
|
||||||
value={form.passwordConfirmation}
|
value={form.passwordConfirmation}
|
||||||
className="bg-base-100"
|
className="bg-base-100"
|
||||||
|
data-testid="password-confirm-input"
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setForm({ ...form, passwordConfirmation: e.target.value })
|
setForm({ ...form, passwordConfirmation: e.target.value })
|
||||||
}
|
}
|
||||||
|
@ -195,6 +201,7 @@ export default function Register() {
|
||||||
<Link
|
<Link
|
||||||
href="https://linkwarden.app/tos"
|
href="https://linkwarden.app/tos"
|
||||||
className="font-semibold underline"
|
className="font-semibold underline"
|
||||||
|
data-testid="terms-of-service-link"
|
||||||
>
|
>
|
||||||
Terms of Service
|
Terms of Service
|
||||||
</Link>{" "}
|
</Link>{" "}
|
||||||
|
@ -202,6 +209,7 @@ export default function Register() {
|
||||||
<Link
|
<Link
|
||||||
href="https://linkwarden.app/privacy-policy"
|
href="https://linkwarden.app/privacy-policy"
|
||||||
className="font-semibold underline"
|
className="font-semibold underline"
|
||||||
|
data-testid="privacy-policy-link"
|
||||||
>
|
>
|
||||||
Privacy Policy
|
Privacy Policy
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -212,6 +220,7 @@ export default function Register() {
|
||||||
<Link
|
<Link
|
||||||
href="mailto:support@linkwarden.app"
|
href="mailto:support@linkwarden.app"
|
||||||
className="font-semibold underline"
|
className="font-semibold underline"
|
||||||
|
data-testid="support-link"
|
||||||
>
|
>
|
||||||
Get in touch
|
Get in touch
|
||||||
</Link>
|
</Link>
|
||||||
|
@ -225,10 +234,15 @@ export default function Register() {
|
||||||
label="Sign Up"
|
label="Sign Up"
|
||||||
className="w-full"
|
className="w-full"
|
||||||
loading={submitLoader}
|
loading={submitLoader}
|
||||||
|
data-testid="register-button"
|
||||||
/>
|
/>
|
||||||
<div className="flex items-baseline gap-1 justify-center">
|
<div className="flex items-baseline gap-1 justify-center">
|
||||||
<p className="w-fit text-neutral">Already have an account?</p>
|
<p className="w-fit text-neutral">Already have an account?</p>
|
||||||
<Link href={"/login"} className="block font-bold">
|
<Link
|
||||||
|
href={"/login"}
|
||||||
|
className="block font-bold"
|
||||||
|
data-testid="login-link"
|
||||||
|
>
|
||||||
Login
|
Login
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
Ŝarĝante…
Reference in New Issue