-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #672 from woowacourse-teams/feat/636-e2e-category-…
…and-search 핵심기능 E2E 테스트 - 카테고리, 검색
- Loading branch information
Showing
8 changed files
with
210 additions
and
1,155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}); |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}; |
Oops, something went wrong.