130 lines
4.4 KiB
JavaScript
130 lines
4.4 KiB
JavaScript
import { expect, test } from '@playwright/test'
|
|
|
|
const adminEmail = 'playwright-admin@example.com'
|
|
const adminPassword = 'playwright-admin-password'
|
|
|
|
/**
|
|
* 관리자 화면에 로그인한다.
|
|
* @param {import('@playwright/test').Page} page - 브라우저 페이지
|
|
* @returns {Promise<void>}
|
|
*/
|
|
const loginAdmin = async (page) => {
|
|
await page.goto('/admin/login')
|
|
await page.getByLabel('이메일').fill(adminEmail)
|
|
await page.locator('input[type="password"]').fill(adminPassword)
|
|
|
|
await Promise.all([
|
|
page.waitForResponse((response) =>
|
|
response.url().endsWith('/admin/api/auth/login') && response.status() === 200
|
|
),
|
|
page.getByRole('button', { name: '로그인' }).click()
|
|
])
|
|
await page.waitForURL(/\/admin(?:\/)?$/)
|
|
}
|
|
|
|
/**
|
|
* 관리자 API로 태그를 만든다.
|
|
* @param {import('@playwright/test').APIRequestContext} request - API 요청 컨텍스트
|
|
* @param {{ name: string, slug: string }} tag - 태그 입력값
|
|
* @returns {Promise<void>}
|
|
*/
|
|
const createTag = async (request, tag) => {
|
|
const response = await request.post('/admin/api/tags', {
|
|
data: {
|
|
name: tag.name,
|
|
slug: tag.slug,
|
|
description: '',
|
|
color: '#15171a',
|
|
tagType: 'managed'
|
|
}
|
|
})
|
|
expect([200, 409]).toContain(response.status())
|
|
}
|
|
|
|
/**
|
|
* 관리자 API로 공개 게시물을 만든다.
|
|
* @param {import('@playwright/test').APIRequestContext} request - API 요청 컨텍스트
|
|
* @param {Object} post - 게시물 입력값
|
|
* @returns {Promise<Object>} 생성된 게시물
|
|
*/
|
|
const createPublishedPost = async (request, post) => {
|
|
const response = await request.post('/admin/api/posts', {
|
|
data: {
|
|
title: post.title,
|
|
slug: post.slug,
|
|
content: post.content,
|
|
excerpt: '',
|
|
featuredImage: null,
|
|
showFeaturedImage: false,
|
|
status: 'published',
|
|
publishedAt: new Date().toISOString(),
|
|
tags: post.tags || [],
|
|
tagNames: post.tagNames || {}
|
|
}
|
|
})
|
|
expect(response.status()).toBe(200)
|
|
return await response.json()
|
|
}
|
|
|
|
test('태그 추천을 선택한 뒤에도 다음 후보를 바로 선택할 수 있다', async ({ page }) => {
|
|
await loginAdmin(page)
|
|
await createTag(page.request, {
|
|
name: 'Regression Recent',
|
|
slug: 'regression-recent'
|
|
})
|
|
await createTag(page.request, {
|
|
name: 'Regression Next',
|
|
slug: 'regression-next'
|
|
})
|
|
await createPublishedPost(page.request, {
|
|
title: 'Regression Tag Seed',
|
|
slug: 'regression-tag-seed',
|
|
content: '태그 추천 회귀 테스트용 게시물',
|
|
tags: ['regression-recent'],
|
|
tagNames: {
|
|
'regression-recent': 'Regression Recent'
|
|
}
|
|
})
|
|
|
|
await page.goto('/admin/posts/new')
|
|
await page.waitForLoadState('networkidle')
|
|
await page.getByLabel('태그 추천 목록 열기').click()
|
|
await page.getByRole('option', { name: /Regression Recent/ }).click()
|
|
|
|
await expect(page.getByRole('option', { name: /Regression Next/ })).toBeVisible()
|
|
await page.getByRole('option', { name: /Regression Next/ }).click()
|
|
await expect(page.getByLabel('Regression Recent 태그 삭제')).toBeVisible()
|
|
await expect(page.getByLabel('Regression Next 태그 삭제')).toBeVisible()
|
|
})
|
|
|
|
test('미디어 파생 탭에는 역할 배지가 표시되지 않는다', async ({ page }) => {
|
|
await loginAdmin(page)
|
|
await page.goto('/admin/media')
|
|
await page.waitForLoadState('networkidle')
|
|
|
|
await page.getByRole('button', { name: '대표 이미지' }).click()
|
|
await expect(page.locator('.admin-media__usage-badge')).toHaveCount(0)
|
|
|
|
await page.getByRole('button', { name: '본문 이미지' }).click()
|
|
await expect(page.locator('.admin-media__usage-badge')).toHaveCount(0)
|
|
})
|
|
|
|
test('단일 이미지 size 옵션이 공개 화면과 관리자 미리보기에 반영된다', async ({ page }) => {
|
|
await loginAdmin(page)
|
|
const post = await createPublishedPost(page.request, {
|
|
title: 'Regression Image Width',
|
|
slug: 'regression-image-width',
|
|
content: '{size=180}'
|
|
})
|
|
|
|
await page.goto('/post/regression-image-width')
|
|
const publicImage = page.locator('.prose-image').first()
|
|
await expect(publicImage).toHaveCSS('max-width', '180px')
|
|
|
|
await page.goto(`/admin/posts/${post.id}`)
|
|
await page.waitForLoadState('networkidle')
|
|
await page.getByLabel('미리보기로 전환').click()
|
|
const previewImage = page.locator('.admin-markdown-editor__preview .prose-image').first()
|
|
await expect(previewImage).toHaveCSS('max-width', '180px')
|
|
})
|