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

Conversation

John-Paul-Larkin
Copy link
Member

✨ Codu Pull Request 💻

Pull Request details

  • Add Playwright tests for sorting on the article page

  • Run test for three sorting modes - "Newest", "Oldest" and "Top"

  • Like count added to ArticlePreview

  • I was required to pass the like count to the component, so If it non-zero, I display it on the Article preview with the heart icon.

  • I also added the count as a data attribute, so we can easily remove this if you dont like how it looks.

Article preview with like count

Any Breaking changes

  • None

Copy link

vercel bot commented Oct 20, 2024

@John-Paul-Larkin is attempting to deploy a commit to the Codú Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented Oct 20, 2024

Walkthrough

The changes in this pull request involve updates to the ArticlesPage and ArticlePreview components to incorporate a new likes property. This property is added to the ArticlePreview component's props, allowing it to display the number of likes for each article. Additionally, a new test suite is introduced in the end-to-end tests to validate the sorting of articles based on various criteria, including likes. Overall, these modifications enhance the functionality and testing of the articles feature.

Changes

File Change Summary
app/(app)/articles/_client.tsx Added likes property to ArticlePreview component; updated destructuring in data.pages.map.
components/ArticlePreview/ArticlePreview.tsx Added likes property to Props type; updated rendering logic to display likes with a heart icon.
e2e/articles.spec.ts Introduced a new test suite for article sorting; added tests for sorting by newest, oldest, and top.

Suggested reviewers

  • NiallJoeMaher

🐇 In the meadow, where articles bloom,
Likes now dance, dispelling the gloom.
With hearts that shine and stories to share,
Each click brings joy, a moment so rare.
So hop along, let the likes take flight,
In the world of articles, everything's bright! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (4)
app/(app)/articles/_client.tsx (2)

144-144: LGTM: likes prop added to ArticlePreview.

The addition of the likes prop to the ArticlePreview component is consistent with the earlier changes and allows for the display of the like count. This change aligns well with the PR objectives.

For improved readability, consider grouping related props together. You could move likes next to other user interaction-related props like bookmarkedInitialState. Here's a suggested reordering:

 <ArticlePreview
   key={id}
   id={id}
   slug={slug}
   title={title}
   excerpt={excerpt}
   name={user?.name || ""}
   username={user?.username || ""}
   image={user?.image || ""}
   date={published}
   readTime={readTimeMins}
-  bookmarkedInitialState={currentUserBookmarkedPost}
   likes={likes}
+  bookmarkedInitialState={currentUserBookmarkedPost}
 />

Line range hint 1-190: Overall assessment: Changes look good with a minor suggestion for future improvement.

The modifications to add the likes property to the ArticlesPage component are well-implemented and consistent with the PR objectives. The changes enhance the functionality of the ArticlePreview component by allowing it to display the like count for each article.

For future improvements, consider implementing pagination or infinite scrolling with a "Load More" button instead of automatically loading more articles when the user scrolls to the bottom. This approach can provide better control over data loading and potentially improve performance, especially for users with slower internet connections.

Here's a high-level suggestion for implementing a "Load More" button:

  1. Add a state variable to track if more posts are being loaded.
  2. Replace the useInView hook with a button click handler.
  3. Add a button at the bottom of the article list that triggers the fetchNextPage function.

This change would make the data loading more explicit and give users more control over when they want to load additional content.

components/ArticlePreview/ArticlePreview.tsx (2)

43-43: LGTM: likes property added to Props type.

The likes property is correctly added to the Props type. However, consider making it explicitly optional for better clarity:

likes?: number;

This change would make it clear that the likes property is not required, improving the component's API documentation.


130-138: LGTM: Likes count display implemented correctly.

The likes count and heart icon are appropriately added to the component's render output. The conditional rendering and data attribute are well-implemented.

Consider adding an aria-label to the likes count span for better accessibility:

<span aria-label={`${likes} likes`} data-likes={likes}>{likes}</span>

This change would improve the experience for users relying on screen readers.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 77aa243 and d029c8d.

📒 Files selected for processing (3)
  • app/(app)/articles/_client.tsx (2 hunks)
  • components/ArticlePreview/ArticlePreview.tsx (4 hunks)
  • e2e/articles.spec.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
app/(app)/articles/_client.tsx (1)

127-127: LGTM: Addition of likes property.

The inclusion of the likes property in the destructuring of the posts array is consistent with the PR objectives and the AI-generated summary. This change supports the new like count feature for articles.

To ensure consistency across the codebase, let's verify that the likes property is properly handled in related components and API calls:

components/ArticlePreview/ArticlePreview.tsx (3)

10-10: LGTM: HeartIcon import added correctly.

The HeartIcon import is appropriately added to support the new likes display feature.


59-59: LGTM: likes property correctly destructured.

The likes property is appropriately added to the destructured props, allowing the component to access this value.


Line range hint 1-238: Overall assessment: Well-implemented likes count feature.

The changes to the ArticlePreview component successfully implement the likes count feature as described in the PR objectives. The code is well-structured, maintains consistency with the existing codebase, and includes appropriate conditional rendering. The minor suggestions provided (explicit optional typing for likes prop and adding an aria-label for accessibility) would further enhance the implementation.

e2e/articles.spec.ts Outdated Show resolved Hide resolved
e2e/articles.spec.ts Outdated Show resolved Hide resolved
e2e/articles.spec.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@JohnAllenTech JohnAllenTech left a comment

Choose a reason for hiding this comment

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

Just a few comments. Overall it LGTM

@@ -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.

e2e/articles.spec.ts Outdated Show resolved Hide resolved
e2e/articles.spec.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d029c8d and 036d732.

📒 Files selected for processing (1)
  • e2e/articles.spec.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (1)
e2e/articles.spec.ts (1)

224-239: Test 'Should sort articles by Newest' looks good

The test correctly verifies that articles are sorted from newest to oldest based on their dates.

e2e/articles.spec.ts Outdated Show resolved Hide resolved
e2e/articles.spec.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
e2e/articles.spec.ts (2)

224-239: LGTM! Consider adding a check for the "Newest" filter.

The test logic for checking the newest sorting is correct and handles potential undefined dates well. However, to ensure we're testing the correct filter, consider adding a step to select or verify the "Newest" sorting option.

You could add a step to verify the current filter:

await expect(page.getByRole('button', { name: 'Newest' })).toHaveAttribute('aria-pressed', 'true');

257-276: LGTM! Consider adding error handling for missing like counts.

The test logic for checking the top sorting by likes is correct. It properly navigates to the page with the "top" filter and uses the correct comparison operator (>=) for descending order. The parseInt function now includes the radix parameter as suggested in a previous comment.

Consider adding error handling for cases where the likes count might be missing:

likes: parseInt(
  article.querySelector("[data-likes]")?.getAttribute("data-likes") ?? "0",
  10
),

This ensures that if the data-likes attribute is missing, it defaults to "0" instead of potentially passing undefined to parseInt.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 036d732 and a17ad5b.

📒 Files selected for processing (1)
  • e2e/articles.spec.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (2)
e2e/articles.spec.ts (2)

241-255: LGTM! Correct implementation for "Oldest" sorting test.

The test logic for checking the oldest sorting is correct. It properly navigates to the page with the "oldest" filter, handles potential undefined dates, and uses the correct comparison operator (<=) for ascending order.


224-276: Great addition of sorting tests!

The new tests for sorting articles by Newest, Oldest, and Top (likes) are well-implemented and significantly improve the test coverage for the sorting functionality. They consistently handle edge cases like undefined values and use appropriate comparison logic for each sorting type.

A few minor suggestions have been made to further enhance these tests:

  1. Verifying the active filter in the "Newest" test.
  2. Adding error handling for missing like counts in the "Top" test.

Overall, these additions provide robust end-to-end testing for the article sorting feature.

@NiallJoeMaher
Copy link
Contributor

@JohnAllenTech, this one good to go?

Copy link

vercel bot commented Oct 21, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
codu ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 21, 2024 8:09pm

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a17ad5b and 3e81c53.

📒 Files selected for processing (2)
  • components/ArticlePreview/ArticlePreview.tsx (4 hunks)
  • e2e/articles.spec.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/ArticlePreview/ArticlePreview.tsx
🧰 Additional context used
🔇 Additional comments (3)
e2e/articles.spec.ts (3)

224-239: LGTM: Newest articles sorting test implemented correctly

The test for sorting articles by newest is well-implemented. It correctly extracts dates, handles edge cases, and verifies the descending order.


241-255: LGTM: Oldest articles sorting test implemented correctly

The test for sorting articles by oldest is well-implemented. It correctly navigates to the filtered page, extracts dates, handles edge cases, and verifies the ascending order.


257-276: LGTM: Top articles sorting test implemented correctly

The test for sorting articles by top (likes) is well-implemented. It correctly navigates to the filtered page, extracts likes count, handles edge cases, and verifies the descending order. The parseInt function now includes the radix parameter as suggested in a previous comment.

e2e/articles.spec.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@JohnAllenTech JohnAllenTech left a comment

Choose a reason for hiding this comment

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

Just a small comment. Tests LGTM

e2e/articles.spec.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (4)
e2e/articles.spec.ts (4)

80-95: LGTM! Consider adding a check for the number of articles.

The test logic for sorting by newest is correct and handles potential undefined dates well. To enhance the test's robustness, consider adding an assertion to check if there are actually articles present before performing the sorting check.

You could add this assertion after line 88:

expect(articles.length).toBeGreaterThan(0);

97-111: LGTM! Consider refactoring to reduce duplication.

The test logic for sorting by oldest is correct and handles potential undefined dates well. However, there's significant duplication between this test and the "Newest" test.

Consider creating a helper function to reduce duplication:

function testArticleSorting(sortType: string, url: string, compareFn: (a: Date, b: Date) => boolean) {
  test(`Should sort articles by ${sortType}`, async ({ page }) => {
    await page.goto(url);
    await page.waitForSelector("article");

    const articles = await page.$$eval("article", (articles) => {
      return articles.map((article) => ({
        date: article.querySelector("time")?.dateTime,
      }));
    });

    expect(articles.length).toBeGreaterThan(0);

    const isSorted = articles.every((article, index, arr) => {
      if (index === arr.length - 1) return true;
      if (!article.date || !arr[index + 1].date) return false;
      return compareFn(new Date(article.date), new Date(arr[index + 1].date!));
    });

    expect(isSorted).toBeTruthy();
  });
}

// Usage
testArticleSorting("Newest", "http://localhost:3000/articles", (a, b) => a >= b);
testArticleSorting("Oldest", "http://localhost:3000/articles?filter=oldest", (a, b) => a <= b);

This refactoring would make the tests more maintainable and easier to extend in the future.


113-132: LGTM! Consider refactoring and adding error handling.

The test logic for sorting by top likes is correct. However, there are a few improvements that can be made:

  1. Error handling for parsing likes count.
  2. Reducing duplication with other sorting tests.
  3. Adding a check for the number of articles.

Consider updating the helper function suggested earlier to include this test:

function testArticleSorting<T>(
  sortType: string,
  url: string,
  extractFn: (article: Element) => T,
  compareFn: (a: T, b: T) => boolean
) {
  test(`Should sort articles by ${sortType}`, async ({ page }) => {
    await page.goto(url);
    await page.waitForSelector("article");

    const articles = await page.$$eval("article", (articles, extract) => 
      articles.map(extract as (article: Element) => T), extractFn);

    expect(articles.length).toBeGreaterThan(0);

    const isSorted = articles.every((article, index, arr) => 
      index === arr.length - 1 || compareFn(article, arr[index + 1]));

    expect(isSorted).toBeTruthy();
  });
}

// Usage
testArticleSorting(
  "Top - likes",
  "http://localhost:3000/articles?filter=top",
  (article) => {
    const likesStr = article.querySelector("[data-likes]")?.getAttribute("data-likes") || "0";
    const likes = parseInt(likesStr, 10);
    if (isNaN(likes)) {
      throw new Error(`Invalid likes count: ${likesStr}`);
    }
    return likes;
  },
  (a, b) => a >= b
);

This refactoring addresses the duplication issue and adds error handling for parsing the likes count.


80-132: Overall, good addition of sorting tests. Consider refactoring for improved maintainability.

The new tests for sorting articles by Newest, Oldest, and Top likes are valuable additions to the test suite. They cover important functionality and are generally well-implemented. However, there are a few areas for improvement:

  1. Reduce code duplication by creating a helper function for sorting tests.
  2. Add checks for the number of articles before performing sorting checks.
  3. Improve error handling, particularly for parsing likes count.
  4. Consider using Playwright's baseURL configuration to avoid hardcoding URLs in tests.

Implementing these suggestions will make the tests more robust and easier to maintain in the future.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3e81c53 and d7a1c07.

📒 Files selected for processing (1)
  • e2e/articles.spec.ts (1 hunks)
🧰 Additional context used

@NiallJoeMaher NiallJoeMaher merged commit e4102dd into codu-code:develop Oct 22, 2024
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants