mirror of
https://github.com/langgenius/dify.git
synced 2026-05-07 02:46:32 +08:00
Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: jyong <718720800@qq.com> Co-authored-by: Yansong Zhang <916125788@qq.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: hj24 <mambahj24@gmail.com> Co-authored-by: hj24 <huangjian@dify.ai> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com> Co-authored-by: CodingOnStar <hanxujiang@dify.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: 非法操作 <hjlarry@163.com> Co-authored-by: Ayush Baluni <73417844+aayushbaluni@users.noreply.github.com> Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com> Co-authored-by: jimcody1995 <jjimcody@gmail.com> Co-authored-by: James <63717587+jamesrayammons@users.noreply.github.com> Co-authored-by: Yunlu Wen <yunlu.wen@dify.ai> Co-authored-by: Stephen Zhou <hi@hyoban.cc> Co-authored-by: Coding On Star <447357187@qq.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jerryzai <jerryzh8710@protonmail.com> Co-authored-by: NVIDIAN <speedy.hpc@hotmail.com> Co-authored-by: ai-hpc <ai-hpc@users.noreply.github.com> Co-authored-by: Asuka Minato <i@asukaminato.eu.org> Co-authored-by: Junghwan <70629228+shaun0927@users.noreply.github.com> Co-authored-by: HeYinKazune <70251095+HeYin-OS@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: yyh <yuanyouhuilyz@gmail.com> Co-authored-by: Jingyi <jingyi.qi@dify.ai> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: sxxtony <166789813+sxxtony@users.noreply.github.com>
101 lines
3.2 KiB
TypeScript
101 lines
3.2 KiB
TypeScript
import type { Browser } from '@playwright/test'
|
|
import type { DifyWorld } from './world'
|
|
import { mkdir, writeFile } from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { After, AfterAll, Before, BeforeAll, setDefaultTimeout, Status } from '@cucumber/cucumber'
|
|
import { chromium } from '@playwright/test'
|
|
import { AUTH_BOOTSTRAP_TIMEOUT_MS, ensureAuthenticatedState } from '../../fixtures/auth'
|
|
import { deleteTestApp } from '../../support/api'
|
|
import { baseURL, cucumberHeadless, cucumberSlowMo } from '../../test-env'
|
|
|
|
const e2eRoot = fileURLToPath(new URL('../..', import.meta.url))
|
|
const artifactsDir = path.join(e2eRoot, 'cucumber-report', 'artifacts')
|
|
|
|
let browser: Browser | undefined
|
|
|
|
setDefaultTimeout(60_000)
|
|
|
|
const sanitizeForPath = (value: string) =>
|
|
value.replaceAll(/[^\w-]+/g, '-').replaceAll(/^-+|-+$/g, '')
|
|
|
|
const writeArtifact = async (
|
|
scenarioName: string,
|
|
extension: 'html' | 'png',
|
|
contents: Buffer | string,
|
|
) => {
|
|
const artifactPath = path.join(
|
|
artifactsDir,
|
|
`${Date.now()}-${sanitizeForPath(scenarioName || 'scenario')}.${extension}`,
|
|
)
|
|
await writeFile(artifactPath, contents)
|
|
|
|
return artifactPath
|
|
}
|
|
|
|
BeforeAll({ timeout: AUTH_BOOTSTRAP_TIMEOUT_MS }, async () => {
|
|
await mkdir(artifactsDir, { recursive: true })
|
|
|
|
browser = await chromium.launch({
|
|
headless: cucumberHeadless,
|
|
slowMo: cucumberSlowMo,
|
|
})
|
|
|
|
console.log(`[e2e] session cache bootstrap against ${baseURL}`)
|
|
await ensureAuthenticatedState(browser, baseURL)
|
|
})
|
|
|
|
Before(async function (this: DifyWorld, { pickle }) {
|
|
if (!browser)
|
|
throw new Error('Shared Playwright browser is not available.')
|
|
|
|
const isUnauthenticatedScenario = pickle.tags.some(tag => tag.name === '@unauthenticated')
|
|
|
|
if (isUnauthenticatedScenario)
|
|
await this.startUnauthenticatedSession(browser)
|
|
else await this.startAuthenticatedSession(browser)
|
|
|
|
this.scenarioStartedAt = Date.now()
|
|
|
|
const tags = pickle.tags.map(tag => tag.name).join(' ')
|
|
console.log(`[e2e] start ${pickle.name}${tags ? ` ${tags}` : ''}`)
|
|
})
|
|
|
|
After(async function (this: DifyWorld, { pickle, result }) {
|
|
const elapsedMs = this.scenarioStartedAt ? Date.now() - this.scenarioStartedAt : undefined
|
|
|
|
if (result?.status !== Status.PASSED && this.page) {
|
|
const screenshot = await this.page.screenshot({
|
|
fullPage: true,
|
|
})
|
|
const screenshotPath = await writeArtifact(pickle.name, 'png', screenshot)
|
|
this.attach(screenshot, 'image/png')
|
|
|
|
const html = await this.page.content()
|
|
const htmlPath = await writeArtifact(pickle.name, 'html', html)
|
|
this.attach(html, 'text/html')
|
|
|
|
if (this.consoleErrors.length > 0)
|
|
this.attach(`Console Errors:\n${this.consoleErrors.join('\n')}`, 'text/plain')
|
|
|
|
if (this.pageErrors.length > 0)
|
|
this.attach(`Page Errors:\n${this.pageErrors.join('\n')}`, 'text/plain')
|
|
|
|
this.attach(`Artifacts:\n${[screenshotPath, htmlPath].join('\n')}`, 'text/plain')
|
|
}
|
|
|
|
const status = result?.status || 'UNKNOWN'
|
|
console.log(
|
|
`[e2e] end ${pickle.name} status=${status}${elapsedMs ? ` durationMs=${elapsedMs}` : ''}`,
|
|
)
|
|
|
|
for (const id of this.createdAppIds) await deleteTestApp(id).catch(() => {})
|
|
|
|
await this.closeSession()
|
|
})
|
|
|
|
AfterAll(async () => {
|
|
await browser?.close()
|
|
browser = undefined
|
|
})
|