Skip to content

Commit

Permalink
Merge pull request #672 from woowacourse-teams/feat/636-e2e-category-…
Browse files Browse the repository at this point in the history
…and-search

핵심기능 E2E 테스트 - 카테고리, 검색
  • Loading branch information
Jaymyong66 authored Sep 20, 2024
2 parents 1b3ac4b + 11aa70e commit daeca6f
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 1,155 deletions.
29 changes: 29 additions & 0 deletions frontend/e2eTests/category.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Page } from '@playwright/test';

interface Props {
page: Page;
categoryName: string;
}

export const getCategoryButton = ({ page, categoryName }: Props) => page.getByRole('button', { name: categoryName });

export const createCategory = async ({ page, categoryName }: Props) => {
await page.getByRole('button', { name: '카테고리 편집' }).click();

await page.getByRole('button', { name: '+ 카테고리 추가' }).click();
await page.getByPlaceholder('카테고리 입력').fill(categoryName);
await page.getByPlaceholder('카테고리 입력').press('Enter');

await page.getByRole('button', { name: '저장' }).click();
};

export const deleteCategory = async ({ page, categoryName }: Props) => {
await page.getByRole('button', { name: '카테고리 편집' }).click();

const categoryInEditModal = page.getByText(categoryName).nth(1);

await categoryInEditModal.hover();
await page.getByRole('button', { name: '카테고리 삭제' }).click();

await page.getByRole('button', { name: '저장' }).click();
};
95 changes: 95 additions & 0 deletions frontend/e2eTests/category.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { test, expect } from '@playwright/test';

import { createCategory, deleteCategory, getCategoryButton } from './category.actions';
import { loginToCodezap, waitForSuccess } from './utils';

test.beforeEach(async ({ page }) => {
await loginToCodezap({
page,
id: process.env.PLAYWRIGHT_TEST_ID || '',
password: process.env.PLAYWRIGHT_TEST_PASSWORD || '',
});
});

test('카테고리 편집 모달에서 새 카테고리를 추가 및 삭제할 수 있다.', async ({ page, browserName }) => {
const newCategoryName = `생성테스트-${browserName}`;

await createCategory({ page, categoryName: newCategoryName });

await waitForSuccess({ page, apiUrl: '/categories' });

const newCategoryButton = getCategoryButton({ page, categoryName: newCategoryName });

await expect(newCategoryButton).toBeVisible();

// 다음 테스트를 위해 테스트용 카테고리 삭제
await deleteCategory({ page, categoryName: newCategoryName });

await waitForSuccess({ page, apiUrl: '/categories' });

await expect(newCategoryButton).not.toBeVisible();
});

test('카테고리 편집 모달에서 카테고리명을 수정 및 삭제할 수 있다.', async ({ page, browserName }) => {
const newCategoryName = `수정테스트-${browserName}`;
const editedCategoryName = `수정완료-${browserName}`;

// 수정할 카테고리 생성
await createCategory({ page, categoryName: newCategoryName });

await waitForSuccess({ page, apiUrl: '/categories' });

const newCategoryButton = getCategoryButton({ page, categoryName: newCategoryName });

await expect(newCategoryButton).toBeVisible();

// 카테고리 수정
await page.getByRole('button', { name: '카테고리 편집' }).click();

const newCategoryInEditModal = page.getByText(newCategoryName).nth(1);

await newCategoryInEditModal.hover();
await page.getByRole('button', { name: '카테고리 이름 변경' }).click();
await page.getByPlaceholder('카테고리 입력').click();
await page.getByPlaceholder('카테고리 입력').fill(editedCategoryName);
await page.getByRole('button', { name: '저장' }).click();

const editedCategoryButton = getCategoryButton({ page, categoryName: editedCategoryName });

await expect(editedCategoryButton).toBeVisible();

// 다음 테스트를 위해 테스트용 카테고리 삭제
await deleteCategory({ page, categoryName: editedCategoryName });

await waitForSuccess({ page, apiUrl: '/categories' });
await expect(editedCategoryButton).not.toBeVisible();
});

test('카테고리는 최대 15글자까지만 입력할 수 있다.', async ({ page, browserName }) => {
const rawCategoryName = `최대글자수테스트-${browserName}`;
const expectedCategoryName = rawCategoryName.slice(0, 15);

await page.getByRole('button', { name: '카테고리 편집' }).click();
await page.getByRole('button', { name: '+ 카테고리 추가' }).click();
const categoryInput = page.getByPlaceholder('카테고리 입력');

await categoryInput.click();

for (const char of rawCategoryName) {
await page.keyboard.type(char);
}

await page.getByRole('button', { name: '저장' }).click();

await waitForSuccess({ page, apiUrl: '/categories' });

const newCategoryButton = getCategoryButton({ page, categoryName: expectedCategoryName });

await expect(newCategoryButton).toBeVisible();

// 다음 테스트를 위해 테스트용 카테고리 삭제
await deleteCategory({ page, categoryName: expectedCategoryName });

await waitForSuccess({ page, apiUrl: '/categories' });
await expect(newCategoryButton).not.toBeVisible();
});
15 changes: 0 additions & 15 deletions frontend/e2eTests/example.spec.ts

This file was deleted.

15 changes: 15 additions & 0 deletions frontend/e2eTests/search.actions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Page } from '@playwright/test';

interface Props {
page: Page;
keyword: string;
}

export const searchTemplates = async ({ page, keyword }: Props) => {
const searchInput = page.getByPlaceholder('검색');

await searchInput.waitFor({ state: 'visible' });
await searchInput.click();
await searchInput.fill(keyword);
await searchInput.press('Enter');
};
30 changes: 30 additions & 0 deletions frontend/e2eTests/search.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { test, expect } from '@playwright/test';

import { searchTemplates } from './search.actions';
import { loginToCodezap, waitForSuccess } from './utils';

test.beforeEach(async ({ page }) => {
await loginToCodezap({
page,
id: process.env.PLAYWRIGHT_TEST_ID || '',
password: process.env.PLAYWRIGHT_TEST_PASSWORD || '',
});
});

test('검색창에 `테스트`를 입력하면 `테스트`가 내용에 포함된 템플릿 목록을 확인할 수 있다.', async ({ page }) => {
const keyword = '테스트';

await searchTemplates({ page, keyword });

await waitForSuccess({ page, apiUrl: '/templates?keyword' });
await expect(page.getByRole('link', { name: /테스트/ })).toBeVisible();
});

test('검색창에 `ㅁㅅㅌㅇ`를 입력할 경우 `검색 결과가 없습니다`가 나온다.', async ({ page }) => {
const keyword = 'ㅁㅅㅌㅇ';

await searchTemplates({ page, keyword });

await waitForSuccess({ page, apiUrl: '/templates?keyword' });
await expect(page.locator('div').filter({ hasText: /^검색 결과가 없습니다\.$/ })).toBeVisible();
});
32 changes: 32 additions & 0 deletions frontend/e2eTests/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { Page } from '@playwright/test';

interface LoginToCodezapProps {
page: Page;
id: string;
password: string;
}

export const loginToCodezap = async ({ page, id, password }: LoginToCodezapProps) => {
await page.goto('/');
await page.getByRole('link', { name: '로그인', exact: true }).getByRole('button').click();
await page
.locator('div')
.filter({ hasText: /^아이디 \(닉네임\)$/ })
.locator('div')
.click();
await page.locator('input[type="text"]').fill(id);
await page.locator('input[type="text"]').press('Tab');
await page.locator('input[type="password"]').fill(password);
await page.locator('form').getByRole('button', { name: '로그인' }).click();

await waitForSuccess({ page, apiUrl: '/login' });
};

interface WaitForSuccessProps {
page: Page;
apiUrl: string;
}

export const waitForSuccess = async ({ page, apiUrl }: WaitForSuccessProps) => {
await page.waitForResponse((response) => response.url().includes(apiUrl) && response.status() === 200);
};
Loading

0 comments on commit daeca6f

Please sign in to comment.