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

Feat/e2e testing for article sorting #1159

2 changes: 2 additions & 0 deletions app/(app)/articles/_client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ const ArticlesPage = () => {
readTimeMins,
id,
currentUserBookmarkedPost,
likes,
}) => {
// TODO: Bump posts that were recently updated to the top and show that they were updated recently
if (!published) return null;
Expand All @@ -140,6 +141,7 @@ const ArticlesPage = () => {
date={published}
readTime={readTimeMins}
bookmarkedInitialState={currentUserBookmarkedPost}
likes={likes}
/>
);
},
Expand Down
12 changes: 12 additions & 0 deletions components/ArticlePreview/ArticlePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Temporal } from "@js-temporal/polyfill";
import {
BookmarkIcon,
EllipsisHorizontalIcon,
HeartIcon,
} from "@heroicons/react/20/solid";
import {
Menu,
Expand Down Expand Up @@ -39,6 +40,7 @@ type Props = {
menuOptions?: Array<ButtonOptions | LinkOptions>;
showBookmark?: boolean;
bookmarkedInitialState?: boolean;
likes: number;
};

const ArticlePreview: NextPage<Props> = ({
Expand All @@ -54,6 +56,7 @@ const ArticlePreview: NextPage<Props> = ({
menuOptions,
showBookmark = true,
bookmarkedInitialState = false,
likes,
}) => {
const { data: session } = useSession();
const [bookmarked, setIsBookmarked] = useState(bookmarkedInitialState);
Expand Down Expand Up @@ -125,6 +128,15 @@ const ArticlePreview: NextPage<Props> = ({
<>
<span aria-hidden="true">&middot;</span>
<span>{readTime} min read</span>
{likes && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting because you need a way to know how many likes an article has without clicking into it. That makes sense

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to know the amount of likes before it's loaded? 🤔 I don't think it's shown on the card?

Copy link
Member Author

@John-Paul-Larkin John-Paul-Larkin Oct 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NiallJoeMaher

Why do we need to know the amount of likes before it's loaded? 🤔 I don't think it's shown on the card?

I added it to the card in this PR.
if you take a look at the PR description you will see how it looks.
Heart icon with the like count. If there are no likes it wont show.

I figured you wouldnt like this 🤣 so I added it as a data attribute and can edit to remove it from the card.
The like count has to be included somewhere in the html, so playwright can grab it. For the sort by top test.

<>
<span aria-hidden="true">&middot;</span>
<span data-likes={likes}>{likes}</span>
<HeartIcon
className={`relative top-[1px] h-3.5 w-3.5 fill-red-400`}
/>
</>
)}
</>
)}
<div className="flex items-center justify-start"></div>
Expand Down
54 changes: 54 additions & 0 deletions e2e/articles.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,60 @@ test.describe("Unauthenticated Articles Page", () => {
page.getByText("Sign in or sign up to leave a comment"),
).toBeVisible();
});

test("Should sort articles by Newest", async ({ page }) => {
await page.goto("http://localhost:3000/articles");
await page.waitForSelector("article");

const articles = await page.$$eval("article", (articles) => {
return articles.map((article) => ({
date: article.querySelector("time")?.dateTime,
}));
});
const isSortedNewest = articles.every((article, index, arr) => {
if (index === arr.length - 1) return true;
if (!article.date || !arr[index + 1].date) return false;
return new Date(article.date) >= new Date(arr[index + 1].date!);
});
expect(isSortedNewest).toBeTruthy();
});

test("Should sort articles by Oldest", async ({ page }) => {
await page.goto("http://localhost:3000/articles?filter=oldest");
await page.waitForSelector("article");
const articles = await page.$$eval("article", (articles) => {
return articles.map((article) => ({
date: article.querySelector("time")?.dateTime,
}));
});
const isSortedOldest = articles.every((article, index, arr) => {
if (index === arr.length - 1) return true;
if (!article.date || !arr[index + 1].date) return false;
return new Date(article.date) <= new Date(arr[index + 1].date!);
});
expect(isSortedOldest).toBeTruthy();
});

test("Should sort articles by Top - likes", async ({ page }) => {
await page.goto("http://localhost:3000/articles?filter=top");
await page.waitForSelector("article");

const articles = await page.$$eval("article", (articles) => {
return articles.map((article) => ({
likes: parseInt(
article.querySelector("[data-likes]")?.getAttribute("data-likes") ||
"0",
10,
),
}));
});

const isSortedTop = articles.every((article, index, arr) => {
if (index === arr.length - 1) return true;
return article.likes >= arr[index + 1].likes;
});
expect(isSortedTop).toBeTruthy();
});
});

test.describe("Authenticated Articles Page", () => {
Expand Down
Loading