feat: add worker operations and fix gitea actions
Some checks failed
docker-images / build-and-push (admin, admin, termi-astro-admin, admin/Dockerfile) (push) Successful in 29s
docker-images / build-and-push (backend, backend, termi-astro-backend, backend/Dockerfile) (push) Successful in 33m13s
docker-images / build-and-push (frontend, frontend, termi-astro-frontend, frontend/Dockerfile) (push) Successful in 58s
ui-regression / playwright-regression (push) Failing after 13m24s
Some checks failed
docker-images / build-and-push (admin, admin, termi-astro-admin, admin/Dockerfile) (push) Successful in 29s
docker-images / build-and-push (backend, backend, termi-astro-backend, backend/Dockerfile) (push) Successful in 33m13s
docker-images / build-and-push (frontend, frontend, termi-astro-frontend, frontend/Dockerfile) (push) Successful in 58s
ui-regression / playwright-regression (push) Failing after 13m24s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { expect, test, type Page } from '@playwright/test'
|
||||
|
||||
import { getDebugState, loginAdmin, resetMockState } from './helpers'
|
||||
import { getDebugState, loginAdmin, MOCK_BASE_URL, resetMockState } from './helpers'
|
||||
|
||||
test.beforeEach(async ({ request }) => {
|
||||
await resetMockState(request)
|
||||
@@ -39,6 +39,7 @@ test('后台登录、导航与关键模块页面可加载', async ({ page }) =>
|
||||
{ label: '评测', url: /\/reviews$/, text: '《漫长的季节》' },
|
||||
{ label: '媒体库', url: /\/media$/, text: '漫长的季节封面' },
|
||||
{ label: '订阅', url: /\/subscriptions$/, text: 'watcher@example.com' },
|
||||
{ label: 'Workers', url: /\/workers$/, text: '异步 Worker 控制台' },
|
||||
{ label: '审计', url: /\/audit$/, text: 'playwright-smoke' },
|
||||
{ label: '设置', url: /\/settings$/, text: 'InitCool' },
|
||||
]
|
||||
@@ -50,6 +51,17 @@ test('后台登录、导航与关键模块页面可加载', async ({ page }) =>
|
||||
}
|
||||
})
|
||||
|
||||
test('后台 dashboard worker 健康卡片可跳转到带筛选的 workers', async ({ page }) => {
|
||||
await loginAdmin(page)
|
||||
|
||||
await expect(page.locator('main')).toContainText('Worker 活动')
|
||||
|
||||
await page.getByTestId('dashboard-worker-card-failed').click()
|
||||
await expect(page).toHaveURL(/\/workers\?status=failed$/)
|
||||
await expect(page.locator('main')).toContainText('异步 Worker 控制台')
|
||||
await expect(page.locator('main')).toContainText('failed')
|
||||
})
|
||||
|
||||
test('后台可以审核评论和友链,并更新站点设置', async ({ page }) => {
|
||||
await loginAdmin(page)
|
||||
|
||||
@@ -136,8 +148,21 @@ test('后台可完成订阅 CRUD、测试投递与 digest 入队', async ({ page
|
||||
await expect(row).toContainText('Deep Regression Updated')
|
||||
|
||||
await row.getByTestId(/subscription-test-/).click()
|
||||
await expect(page.getByTestId('subscriptions-last-job')).toBeVisible()
|
||||
await page.getByTestId('subscriptions-last-job').click()
|
||||
await expect(page).toHaveURL(/\/workers\?job=\d+$/)
|
||||
await expect(page.locator('main')).toContainText('subscription.test')
|
||||
|
||||
await page.getByRole('link', { name: '订阅' }).click()
|
||||
await page.getByTestId('subscriptions-send-weekly').click()
|
||||
await expect(page.getByTestId('subscriptions-last-job')).toBeVisible()
|
||||
await page.getByTestId('subscriptions-send-monthly').click()
|
||||
await expect(page.getByTestId(/^subscription-delivery-job-/).first()).toBeVisible()
|
||||
await page.getByTestId(/^subscription-delivery-job-/).first().click()
|
||||
await expect(page).toHaveURL(/\/workers\?job=\d+$/)
|
||||
await expect(page.locator('main')).toContainText('worker.notification_delivery')
|
||||
|
||||
await page.getByRole('link', { name: '订阅' }).click()
|
||||
|
||||
let state = await getDebugState(request)
|
||||
expect(
|
||||
@@ -146,6 +171,9 @@ test('后台可完成订阅 CRUD、测试投递与 digest 入队', async ({ page
|
||||
).toBeTruthy()
|
||||
expect(state.deliveries.some((item: { event_type: string }) => item.event_type === 'digest.weekly')).toBeTruthy()
|
||||
expect(state.deliveries.some((item: { event_type: string }) => item.event_type === 'digest.monthly')).toBeTruthy()
|
||||
expect(
|
||||
state.worker_jobs.some((item: { worker_name: string }) => item.worker_name === 'worker.notification_delivery'),
|
||||
).toBeTruthy()
|
||||
|
||||
await row.getByTestId(/subscription-delete-/).click()
|
||||
await expect(row).toHaveCount(0)
|
||||
@@ -156,6 +184,33 @@ test('后台可完成订阅 CRUD、测试投递与 digest 入队', async ({ page
|
||||
).toBeFalsy()
|
||||
})
|
||||
|
||||
test('后台可查看 worker 控制台并执行 digest / retry / job 重跑', async ({ page, request }) => {
|
||||
await loginAdmin(page)
|
||||
await page.getByRole('link', { name: 'Workers' }).click()
|
||||
|
||||
await page.getByTestId('workers-run-weekly').click()
|
||||
await expect(page.locator('main')).toContainText('task.send_weekly_digest')
|
||||
|
||||
await page.getByTestId('workers-retry-job').click()
|
||||
|
||||
let state = await getDebugState(request)
|
||||
expect(
|
||||
state.worker_jobs.some((item: { worker_name: string }) => item.worker_name === 'task.send_weekly_digest'),
|
||||
).toBeTruthy()
|
||||
expect(
|
||||
state.worker_jobs.some(
|
||||
(item: { worker_name: string; parent_job_id: number | null }) =>
|
||||
item.worker_name === 'task.send_weekly_digest' && item.parent_job_id !== null,
|
||||
),
|
||||
).toBeTruthy()
|
||||
|
||||
await page.getByTestId('workers-run-retry').click()
|
||||
state = await getDebugState(request)
|
||||
expect(
|
||||
state.worker_jobs.some((item: { worker_name: string }) => item.worker_name === 'task.retry_deliveries'),
|
||||
).toBeTruthy()
|
||||
})
|
||||
|
||||
test('后台可完成文章创建、保存、版本恢复与删除', async ({ page, request }) => {
|
||||
await loginAdmin(page)
|
||||
await page.getByRole('link', { name: '文章' }).click()
|
||||
@@ -209,6 +264,15 @@ test('后台可完成媒体库上传/元数据/替换/删除,并执行设置
|
||||
await loginAdmin(page)
|
||||
|
||||
await page.getByRole('link', { name: '媒体库' }).click()
|
||||
await page.getByTestId('media-remote-url').fill(`${MOCK_BASE_URL}/media-files/remote-playwright.svg`)
|
||||
await page.getByTestId('media-remote-title').fill('Remote Playwright Cover')
|
||||
await page.getByTestId('media-remote-download').click()
|
||||
await expect(page.getByTestId('media-last-remote-job')).toBeVisible()
|
||||
await page.getByTestId('media-last-remote-job').click()
|
||||
await expect(page).toHaveURL(/\/workers\?job=\d+$/)
|
||||
await expect(page.locator('main')).toContainText('worker.download_media')
|
||||
await page.getByRole('link', { name: '媒体库' }).click()
|
||||
|
||||
await page.getByTestId('media-upload-input').setInputFiles([
|
||||
buildSvgPayload('deep-regression-cover.svg', 'deep-upload'),
|
||||
])
|
||||
@@ -222,6 +286,13 @@ test('后台可完成媒体库上传/元数据/替换/删除,并执行设置
|
||||
await page.getByTestId('media-save-metadata').click()
|
||||
|
||||
let state = await getDebugState(request)
|
||||
expect(
|
||||
state.media.some(
|
||||
(item: { title: string; key: string }) =>
|
||||
item.title === 'Remote Playwright Cover' &&
|
||||
String(item.key || '').includes('post-covers/'),
|
||||
),
|
||||
).toBeTruthy()
|
||||
expect(
|
||||
state.media.some(
|
||||
(item: { title: string; alt_text: string; tags: string[] }) =>
|
||||
|
||||
@@ -24,6 +24,36 @@ test('首页过滤、热门区和文章详情链路可用', async ({ page }) =>
|
||||
await expect(page).toHaveURL(/\/articles\/playwright-regression-workflow$/)
|
||||
await expect(page.getByRole('heading', { name: 'Playwright 回归工作流设计' })).toBeVisible()
|
||||
await expect(page.locator('.paragraph-comment-marker').first()).toBeVisible()
|
||||
|
||||
await page.goto('/categories/frontend-engineering')
|
||||
await expect(page.getByRole('heading', { name: '前端工程' })).toBeVisible()
|
||||
await expect(page.getByText('Astro 终端博客信息架构实战')).toBeVisible()
|
||||
|
||||
await page.goto('/tags/playwright')
|
||||
await expect(page.getByRole('heading', { name: 'Playwright', exact: true })).toBeVisible()
|
||||
await expect(page.getByText('Playwright 回归工作流设计')).toBeVisible()
|
||||
|
||||
await page.goto('/reviews')
|
||||
await expect(page.getByText('《宇宙探索编辑部》')).toHaveCount(0)
|
||||
await page.goto('/reviews/4')
|
||||
await expect(page.getByRole('heading', { name: '评价不存在' })).toBeVisible()
|
||||
|
||||
await page.goto('/reviews/1')
|
||||
await page.getByRole('link', { name: '#年度最佳' }).click()
|
||||
await expect(page).toHaveURL(/\/reviews\?tag=%E5%B9%B4%E5%BA%A6%E6%9C%80%E4%BD%B3$/)
|
||||
await expect(page.getByText('《漫长的季节》')).toBeVisible()
|
||||
|
||||
await page.goto('/reviews/1')
|
||||
await page.getByRole('link', { name: '动画' }).click()
|
||||
await expect(page).toHaveURL(/\/reviews\?type=anime$/)
|
||||
await expect(page.locator('#reviews-subtitle')).toContainText('动画')
|
||||
await expect(page.getByText('《漫长的季节》')).toBeVisible()
|
||||
|
||||
await page.goto('/reviews/1')
|
||||
await page.getByRole('link', { name: '已完成' }).click()
|
||||
await expect(page).toHaveURL(/\/reviews\?status=completed$/)
|
||||
await expect(page.locator('#reviews-subtitle')).toContainText('已完成')
|
||||
await expect(page.getByText('《漫长的季节》')).toBeVisible()
|
||||
})
|
||||
|
||||
test('文章评论、搜索和 AI 问答链路可用', async ({ page, request }) => {
|
||||
@@ -64,16 +94,27 @@ test('友链申请与订阅确认/偏好/退订链路可用', async ({ page, req
|
||||
expect(friendState.friend_links.some((item: { site_name: string }) => item.site_name === 'Playwright Friend')).toBeTruthy()
|
||||
|
||||
await page.goto('/')
|
||||
await page.locator('[data-subscribe-form] input[name="displayName"]').fill('首页订阅用户')
|
||||
await page.locator('[data-subscribe-form] input[name="email"]').fill('inline-subscriber@example.com')
|
||||
await page.locator('[data-subscribe-form] button[type="submit"]').click()
|
||||
await expect(page.locator('[data-subscribe-status]')).toContainText('订阅')
|
||||
|
||||
await page.locator('[data-subscription-popup-open]').click()
|
||||
await page.locator('[data-subscription-popup-form] input[name="displayName"]').fill('弹窗订阅用户')
|
||||
await page.locator('[data-subscription-popup-email]').fill('playwright-subscriber@example.com')
|
||||
await page.locator('[data-subscription-popup-form] button[type="submit"]').click()
|
||||
await expect(page.locator('[data-subscription-popup-status]')).toContainText('订阅')
|
||||
|
||||
const subscriptionState = await getDebugState(request)
|
||||
const inlineRecord = subscriptionState.subscriptions.find(
|
||||
(item: { target: string; display_name: string }) => item.target === 'inline-subscriber@example.com',
|
||||
)
|
||||
expect(inlineRecord?.display_name).toBe('首页订阅用户')
|
||||
const latest = subscriptionState.subscriptions.find(
|
||||
(item: { target: string }) => item.target === 'playwright-subscriber@example.com',
|
||||
(item: { target: string; display_name: string }) => item.target === 'playwright-subscriber@example.com',
|
||||
)
|
||||
expect(latest).toBeTruthy()
|
||||
expect(latest.display_name).toBe('弹窗订阅用户')
|
||||
|
||||
await page.goto(`/subscriptions/confirm?token=${encodeURIComponent(latest.confirm_token)}`)
|
||||
await expect(page.getByText('订阅已确认')).toBeVisible()
|
||||
|
||||
Reference in New Issue
Block a user