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 [bookmarked, setIsBookmarked] = useState(bookmarkedInitialState);
const howManySavedToShow = 3;
Expand Down Expand Up @@ -124,6 +127,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
48 changes: 48 additions & 0 deletions e2e/articles.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,52 @@ test.describe("Authenticated Articles Page", () => {

await expect(page.getByText(commentContent)).toBeVisible();
});

test.describe("Article sort order on article page", () => {
const sortOptions = ["newest", "oldest", "top"];

for (const sortOption of sortOptions) {
John-Paul-Larkin marked this conversation as resolved.
Show resolved Hide resolved
test(`Should sort articles by ${sortOption}`, async ({ page }) => {
const baseUrl = "http://localhost:3000/articles";
const url =
sortOption === "newest" ? baseUrl : `${baseUrl}?filter=${sortOption}`;
John-Paul-Larkin marked this conversation as resolved.
Show resolved Hide resolved

await page.goto(url);
await page.waitForSelector("article");

const articles = await page.$$eval("article", (articles) => {
return articles.map((article) => ({
date: article.querySelector("time")?.dateTime,
likes: parseInt(
article
.querySelector("[data-likes]")
?.getAttribute("data-likes") || "0",
),
John-Paul-Larkin marked this conversation as resolved.
Show resolved Hide resolved
}));
});

if (sortOption === "newest") {
John-Paul-Larkin marked this conversation as resolved.
Show resolved Hide resolved
const isSortedNewest = articles.every((article, index, arr) => {
if (index === arr.length - 1) return true;
if (!article.date) return false;
return new Date(article.date) >= new Date(arr[index + 1].date!);
});
expect(isSortedNewest).toBeTruthy();
} else if (sortOption === "oldest") {
const isSortedOldest = articles.every((article, index, arr) => {
if (index === arr.length - 1) return true;
if (!article.date) return false;
return new Date(article.date) <= new Date(arr[index + 1].date!);
});
expect(isSortedOldest).toBeTruthy();
} else if (sortOption === "top") {
const isSortedTop = articles.every((article, index, arr) => {
if (index === arr.length - 1) return true;
return article.likes >= arr[index + 1].likes;
});
expect(isSortedTop).toBeTruthy();
}
John-Paul-Larkin marked this conversation as resolved.
Show resolved Hide resolved
});
}
});
});
Loading