💭 Message Board Tests

Add end-to-end tests for the message board

Look to future in the live version of the site: https://supaship.io

Links to e2e tests for the message board:

e2e/message-board.spec.ts

import test, { expect, Page } from "@playwright/test";
import {
  createComment,
  createPost,
  login,
  setupE2eTest,
  signUp,
} from "./utils";

const testUserEmail = "test@test.io";
const testUserPassword = "test123567";
const testUserName = "test";

test.describe("Message Board", () => {
  test.beforeEach(setupE2eTest);

  test.beforeEach(async ({ page }) => {
    page.goto("http://localhost:1337");
  });

  test.describe("not logged in", () => {
    test("can see message board, but cannot interact", async ({ page }) => {
      const messageBoardSignIn = page.locator(
        `[data-e2e="message-board-login"]`
      );
      const createPostForm = page.locator(`[data-e2e="create-post-form"]`);
      await expect(messageBoardSignIn).toHaveCount(1);
      await expect(createPostForm).toHaveCount(0);
    });
    test("can see posts on the message board, but cannot interact", async ({
      page,
      browser,
    }) => {
      const otherUser = await browser.newPage();
      otherUser.goto("http://localhost:1337");
      await signUp(otherUser, testUserEmail, testUserPassword, testUserName);
      const post = await createPost(otherUser, "test post", "test contents");
      await post.click();
      await createComment(otherUser, "test comment");
      page.goto("http://localhost:1337");
      const messageBoardSignIn = page.locator(
        `[data-e2e="message-board-login"]`
      );
      const createPostForm = page.locator(`[data-e2e="create-post-form"]`);
      await expect(messageBoardSignIn).toHaveCount(1);
      await expect(createPostForm).toHaveCount(0);
      const postViaNotLoggedInUser = page.locator("h3", {
        hasText: "test post",
      });
      await postViaNotLoggedInUser.click();
      const postContent = page.locator(`[data-e2e="post-content"]`, {
        hasText: "test contents",
      });
      await expect(postContent).toHaveCount(1);
      const commentContent = page.locator(`[data-e2e="comment-content"]`, {
        hasText: "test comment",
      });
      await expect(commentContent).toHaveCount(1);
      const commentForm = page.locator(`[data-e2e="create-comment-form"]`);
      await expect(commentForm).toHaveCount(0);
      const upvotes = page.locator(`[data-e2e="upvote"]`);
      await expect(upvotes).toHaveCount(2);
      const downvotes = page.locator(`[data-e2e="downvote"]`);
      await expect(downvotes).toHaveCount(2);
      const replyButton = page.locator(`button`, { hasText: "Reply" });
      await expect(replyButton).toHaveCount(1);
      await expect(replyButton).toBeDisabled();
      for (let i = 0; i < 2; i++) {
        await expect(upvotes.nth(i)).toBeDisabled();
        await expect(downvotes.nth(i)).toBeDisabled();
      }
    });
    test("signing up from the message board sends you back to the message board", async ({
      page,
    }) => {
      await signUp(page, testUserEmail, testUserPassword, testUserName);
      const messageBoardTitle = page.locator("h2", {
        hasText: "Message Board",
      });
      await expect(messageBoardTitle).toHaveCount(1);
      const createPostForm = page.locator(`[data-e2e="create-post-form"]`);
      await expect(createPostForm).toHaveCount(1);
    });
    test("logging in from a post message board sends you back to that post", async ({
      page,
    }) => {
      await signUp(page, testUserEmail, testUserPassword, testUserName);
      const post = await createPost(page, "test post", "test contents");
      const logoutButton = page
        .locator("button", { hasText: "Logout" })
        .first();
      await logoutButton.click();
      await post.click();
      const postContent = page.locator(`[data-e2e="post-content"]`, {
        hasText: "test contents",
      });
      await expect(postContent).toHaveCount(1);
      const postUrl = page.url();
      await login(
        page,
        testUserEmail,
        testUserPassword,
        testUserName,
        `[data-e2e="message-board-login"] button`
      );
      expect(page.url()).toBe(postUrl);
      await expect(postContent).toHaveCount(1);
    });
  });

  test.describe("signed in user", () => {
    test.beforeEach(async ({ page }) => {
      await signUp(page, testUserEmail, testUserPassword, testUserName);
    });

    test("can get to message board", async ({ page }) => {
      const messageBoardLink = page.locator("a", { hasText: "Message Board" });
      await messageBoardLink.click();
      const messageBoardHeader = page.locator("h2", {
        hasText: "Message Board",
      });
      await expect(messageBoardHeader).toHaveCount(1);
    });

    test("can create a new post", async ({ page }) => {
      await createPost(page, "Test Post", "This is a test post");
      const postedByMessage = page.locator("p", {
        hasText: `Posted by ${testUserName}`,
      });
      await expect(postedByMessage).toHaveCount(1);
      //   const commentCount = page.locator("p", { hasText: "comments" });
      //   await expect(commentCount).toHaveText("0 comments");
    });

    test("can create a new top level comment", async ({ page }) => {
      const post = await createPost(page, "Test Post", "This is a test post");
      await post.click();
      await createComment(page, "This is a test comment");
      const textArea = page.locator(`textarea`);
      await expect(textArea).toHaveValue("");
      //   const commentCount = page.locator("p", { hasText: "comments" });
      //   await expect(commentCount).toHaveText("1 comments");
    });

    test("nested comment form closes after comment is posted", async ({
      page,
    }) => {
      const post = await createPost(page, "Test Post", "This is a test post");
      await post.click();
      await createComment(page, "This is a test comment");
      const replyButton = page.locator(`button`, { hasText: "Reply" });
      await replyButton.click();
      const commentForms = page.locator(`[data-e2e="create-comment-form"]`);
      await expect(commentForms).toHaveCount(2);
      const nestedCommentForm = commentForms.nth(1);
      await nestedCommentForm
        .locator("textarea")
        .fill("This is a nested comment");
      await page.keyboard.press("Tab");
      await page.keyboard.press("Space");
      const postedComment = page.locator(`[data-e2e="comment-content"]`, {
        hasText: "This is a nested comment",
      });
      await expect(postedComment).toHaveCount(1);
      await expect(commentForms).toHaveCount(1);
    });
  });
});

e2e/up-voting.spec.ts

import test, { expect, Page } from "@playwright/test";
import {
  createComment,
  createPost,
  login,
  setupE2eTest,
  signUp,
} from "./utils";

const testUserEmail = "test@test.io";
const testUserPassword = "test123567";
const testUserName = "test";

test.describe("Up Voting", () => {
  test.beforeEach(setupE2eTest);

  test.beforeEach(async ({ page }) => {
    page.goto("http://localhost:1337");
  });

  test("upvoting works on main page", async ({ page }) => {
    await signUp(page, testUserEmail, testUserPassword, testUserName);
    const post = await createPost(page, "test post", "test contents");
    const upvoteButton = page.locator(`[data-e2e="upvote"]`);
    const downvoteButton = page.locator(`[data-e2e="downvote"]`);
    await expect(upvoteButton).toHaveCount(1);
    await upvoteButton.click();
    const upvoteCount = page.locator(`[data-e2e="upvote-count"]`);
    await expect(upvoteCount).toHaveText("1");
    const filledUpvoteButton = page.locator(
      `[data-e2e="upvote"][data-filled="true"]`
    );
    const filledDownvoteButton = page.locator(
      `[data-e2e="downvote"][data-filled="true"]`
    );
    await expect(filledUpvoteButton).toHaveCount(1);
    await expect(filledDownvoteButton).toHaveCount(0);
    await downvoteButton.click();
    await expect(upvoteCount).toHaveText("-1");
    await expect(filledDownvoteButton).toHaveCount(1);
    await expect(filledUpvoteButton).toHaveCount(0);
  });
  test("upvoting works on post in post page", async ({ page }) => {
    await signUp(page, testUserEmail, testUserPassword, testUserName);
    const post = await createPost(page, "test post", "test contents");
    await post.click();
    const upvoteButton = page.locator(`[data-e2e="upvote"]`);
    const downvoteButton = page.locator(`[data-e2e="downvote"]`);
    await expect(upvoteButton).toHaveCount(1);
    await upvoteButton.click();
    const upvoteCount = page.locator(`[data-e2e="upvote-count"]`);
    await expect(upvoteCount).toHaveText("1");
    const filledUpvoteButton = page.locator(
      `[data-e2e="upvote"][data-filled="true"]`
    );
    const filledDownvoteButton = page.locator(
      `[data-e2e="downvote"][data-filled="true"]`
    );
    await expect(filledUpvoteButton).toHaveCount(1);
    await expect(filledDownvoteButton).toHaveCount(0);
    await downvoteButton.click();
    await expect(upvoteCount).toHaveText("-1");
    await expect(filledDownvoteButton).toHaveCount(1);
    await expect(filledUpvoteButton).toHaveCount(0);
  });
  test("upvoting works on comment in post page", async ({ page }) => {
    await signUp(page, testUserEmail, testUserPassword, testUserName);
    const post = await createPost(page, "test post", "test contents");
    await post.click();
    await createComment(page, "test comment");
    const upvoteButton = page.locator(`[data-e2e="upvote"]`);
    const upvoteCount = page.locator(`[data-e2e="upvote-count"]`);
    const downvoteButton = page.locator(`[data-e2e="downvote"]`);
    await expect(upvoteButton).toHaveCount(2);
    await expect(downvoteButton).toHaveCount(2);
    await expect(upvoteCount).toHaveCount(2);
    for (let i = 0; i < 2; i++) {
      await expect(upvoteCount.nth(i)).toHaveText("0");
      await upvoteButton.nth(i).click();
      await expect(upvoteCount.nth(i)).toHaveText("1");
      const filledUpvoteButton = page.locator(
        `[data-e2e="upvote"][data-filled="true"]`
      );
      const filledDownvoteButton = page.locator(
        `[data-e2e="downvote"][data-filled="true"]`
      );
      await expect(filledUpvoteButton).toHaveCount(1);
      await expect(filledDownvoteButton).toHaveCount(i);
      await downvoteButton.nth(i).click();
      await expect(upvoteCount.nth(i)).toHaveText("-1");
      await expect(filledDownvoteButton).toHaveCount(i + 1);
      await expect(filledUpvoteButton).toHaveCount(0);
    }
  });
});

New createPost() and createComment() util fns in e2e/utils.ts:

export async function createPost(page: Page, title: string, contents: string) {
  page.goto("http://localhost:1337/1");
  const postTitleInput = page.locator(`input[name="title"]`);
  const postContentsInput = page.locator(`textarea[name="contents"]`);
  const postSubmitButton = page.locator(`button[type="submit"]`);
  await postTitleInput.fill(title);
  await postContentsInput.fill(contents);
  await postSubmitButton.click();
  const post = page.locator("h3", { hasText: title });
  await expect(post).toHaveCount(1);
  return post;
}

export async function createComment(page: Page, comment: string) {
  const commentInput = page.locator(`textarea[name="comment"]`);
  const commentSubmitButton = page.locator(`button[type="submit"]`);
  await commentInput.fill(comment);
  await commentSubmitButton.click();
  const createdComment = page.locator("p", { hasText: comment });
  await expect(createdComment).toHaveCount(1);
}

Questions? Let's chat

Open Discord