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

핵심기능 E2E 테스트 - 카테고리, 검색 #672

Merged
merged 9 commits into from
Sep 20, 2024
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