Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 

84 Zeilen
3.9 KiB

  1. import fs from 'node:fs'
  2. import path from 'node:path'
  3. import { expect, type Frame, type Page, type TestInfo } from '@playwright/test'
  4. // @ts-ignore Repository helper reads credentials privately; no trace/storageState is emitted.
  5. import { call, login, fixture, writeFixture, report, work } from '../tools/model-editor-closure-live.mjs'
  6. export { call, login, fixture, writeFixture, report, work }
  7. export async function signIn(page: Page, account = 'root') {
  8. const session = await login(account)
  9. await page.addInitScript(({ accessToken, refreshToken }) => {
  10. if (!sessionStorage.getItem('model-closure-initialized')) {
  11. sessionStorage.setItem('unreal-tran:web:access-token:v1', accessToken)
  12. sessionStorage.setItem('unreal-tran:web:refresh-token:v1', refreshToken || '')
  13. sessionStorage.setItem('model-closure-initialized', '1')
  14. }
  15. }, { accessToken: session.accessToken, refreshToken: session.refreshToken })
  16. return session.accessToken as string
  17. }
  18. export async function openEditor(page: Page, key: 'fox' | 'truck' | string = 'fox') {
  19. const id = fixture().models[key]?.id || key
  20. await page.goto(`/content/models/${id}/edit`)
  21. return readyFrame(page)
  22. }
  23. export async function readyFrame(page: Page): Promise<Frame> {
  24. await expect.poll(() => page.frames().some(frame => frame.url().includes('/legacy-model-editor/editor.html')), { timeout: 60_000 }).toBe(true)
  25. const frame = page.frames().find(frame => frame.url().includes('/legacy-model-editor/editor.html'))!
  26. await frame.waitForFunction(() => {
  27. const editor = (window as any).editorApp
  28. return editor?.apiEditorHydrated && editor?.modelPivot && editor?.apiState === 'ready' && !editor.apiImportBusy && !editor.apiCoverSavePending
  29. }, undefined, { timeout: 90_000 })
  30. await expect(frame.locator('.editor-shell')).toHaveAttribute('data-host-readonly', /true|false/)
  31. return frame
  32. }
  33. export async function saveEditor(frame: Frame) {
  34. await frame.locator('[data-action="save"]').first().click()
  35. await expect.poll(() => frame.evaluate(() => {
  36. const e = (window as any).editorApp
  37. return e.apiState === 'ready' && !e.apiCoverSavePending && !e.apiSession.savePending
  38. })).toBe(true)
  39. }
  40. export async function selectMesh(frame: Frame) {
  41. await frame.locator('[data-selection-scope="part"]').click()
  42. const mesh = await frame.evaluate(() => {
  43. const e = (window as any).editorApp
  44. let selected: any
  45. e.modelPivot.traverse((o: any) => { if (!selected && o.isMesh) selected = o })
  46. return { uuid: selected.uuid, id: selected.userData.editorId, name: selected.name }
  47. })
  48. await frame.locator(`[data-object-id="${mesh.uuid}"]`).click()
  49. return mesh
  50. }
  51. export async function setRange(frame: Frame, selector: string, value: string) {
  52. await frame.locator(selector).evaluate((element, next) => {
  53. (element as HTMLInputElement).value = next
  54. element.dispatchEvent(new Event('input', { bubbles: true }))
  55. element.dispatchEvent(new Event('change', { bubbles: true }))
  56. }, value)
  57. }
  58. export async function shot(page: Page, info: TestInfo, name: string) {
  59. const folder = path.join(report, 'screenshots')
  60. fs.mkdirSync(folder, { recursive: true })
  61. await expect(page.locator('.el-loading-mask:visible')).toHaveCount(0)
  62. const file = path.join(folder, `${name}.png`)
  63. await page.screenshot({ path: file, fullPage: true, animations: 'disabled' })
  64. await info.attach(name, { path: file, contentType: 'image/png' })
  65. }
  66. export async function closeSession(page: Page) {
  67. const token = await page.evaluate(() => sessionStorage.getItem('unreal-tran:web:access-token:v1')).catch(() => null)
  68. if (token) await call('auth/v1/auth/logout', token, {}).catch(() => {})
  69. }
  70. export function evidence(name: string, data: unknown) {
  71. const folder = path.join(report, 'evidence')
  72. fs.mkdirSync(folder, { recursive: true })
  73. fs.writeFileSync(path.join(folder, `${name}.json`), JSON.stringify({ time: new Date().toISOString(), data }, null, 2))
  74. }