Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
203 lines
6.6 KiB
TypeScript
203 lines
6.6 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
import { createAnalyticsReporter, getTestContext } from '../fixtures/analytics-reporter'
|
|
import test from '../fixtures/fixtures'
|
|
import {
|
|
formatPerformanceResults,
|
|
PerformanceTestResult,
|
|
setupPerformanceTest,
|
|
} from '../fixtures/perf-utils'
|
|
import { setup } from '../shared-e2e'
|
|
|
|
test.describe.configure({ mode: 'serial' })
|
|
|
|
function testOutput(result: PerformanceTestResult) {
|
|
// eslint-disable-next-line no-console
|
|
console.log(
|
|
`${result.interaction} Performance: ${result.metrics.averageFps} avg FPS (min: ${result.metrics.minFps}, max: ${result.metrics.maxFps})\n` +
|
|
`${result.comparison.message}\n` +
|
|
'Comparison:' +
|
|
JSON.stringify(result.comparison, null, 2)
|
|
)
|
|
|
|
// Validate performance
|
|
expect(result.metrics.averageFps).toBeGreaterThan(18)
|
|
expect(result.comparison.status).not.toBe('fail')
|
|
|
|
// Update baseline if this is a significant improvement
|
|
if (result.comparison.isImprovement) {
|
|
// eslint-disable-next-line no-console
|
|
console.log('Consider updating baseline - performance improved!')
|
|
}
|
|
}
|
|
|
|
test.describe('Performance Tests', () => {
|
|
test.beforeEach(setup)
|
|
test.setTimeout(120000) // Increase timeout
|
|
test.describe.configure({ mode: 'serial' }) // Run tests in series to avoid resource conflicts
|
|
|
|
test('Baseline FPS Performance - Desktop', async ({
|
|
page,
|
|
context,
|
|
request,
|
|
browserName,
|
|
isMobile,
|
|
}) => {
|
|
if (isMobile) return
|
|
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
const analyticsReporter = createAnalyticsReporter()
|
|
|
|
// Run full performance test suite
|
|
const results = await perfSuite.runFullPerformanceTest()
|
|
|
|
// Log detailed results
|
|
// eslint-disable-next-line no-console
|
|
console.log(formatPerformanceResults(results))
|
|
|
|
// Send analytics
|
|
const testContext = getTestContext('Baseline FPS Performance - Desktop')
|
|
await analyticsReporter.reportPerformanceMetrics(results, testContext)
|
|
|
|
// Send alerts for any regressions
|
|
for (const result of results.filter((r) => r.comparison.status === 'fail')) {
|
|
await analyticsReporter.reportRegressionAlert(result, testContext)
|
|
}
|
|
|
|
// Check for any failures
|
|
const failedTests = results.filter((result) => result.comparison.status === 'fail')
|
|
if (failedTests.length > 0) {
|
|
const failureMessages = failedTests
|
|
.map((t) => `${t.interaction}: ${t.comparison.message}`)
|
|
.join('\n')
|
|
expect(failedTests.length, `Performance tests failed:\n${failureMessages}`).toBe(0)
|
|
}
|
|
|
|
// Warn about any significant changes
|
|
const warningTests = results.filter((result) => result.comparison.status === 'warning')
|
|
if (warningTests.length > 0) {
|
|
console.warn('Performance warnings detected:')
|
|
warningTests.forEach((t) => {
|
|
console.warn(` ${t.interaction}: ${t.comparison.message}`)
|
|
})
|
|
}
|
|
|
|
// Assert overall test health
|
|
expect(results.length).toBeGreaterThan(0)
|
|
|
|
// Ensure all tests have reasonable FPS values
|
|
results.forEach((result) => {
|
|
expect(result.metrics.averageFps).toBeGreaterThan(0)
|
|
expect(result.metrics.averageFps).toBeLessThanOrEqual(60)
|
|
})
|
|
})
|
|
|
|
test('Shape Rotation Performance', async ({ page, context, request, browserName, isMobile }) => {
|
|
if (isMobile) return
|
|
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
await perfSuite.setupHeavyBoard()
|
|
|
|
testOutput(await perfSuite.testShapeRotation())
|
|
})
|
|
|
|
test('Shape Dragging Performance', async ({ page, context, request, browserName, isMobile }) => {
|
|
if (isMobile) return
|
|
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
await perfSuite.setupHeavyBoard()
|
|
|
|
testOutput(await perfSuite.testShapeDragging())
|
|
})
|
|
|
|
test('Shape Resizing Performance', async ({ page, context, request, browserName, isMobile }) => {
|
|
if (isMobile) return
|
|
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
await perfSuite.setupHeavyBoard(50)
|
|
|
|
testOutput(await perfSuite.testShapeResizing())
|
|
})
|
|
|
|
test('Canvas Panning Performance', async ({ page, context, request, browserName, isMobile }) => {
|
|
if (isMobile) return
|
|
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
await perfSuite.setupHeavyBoard(1000)
|
|
|
|
testOutput(await perfSuite.testCanvasPanning())
|
|
})
|
|
|
|
test('Canvas Zooming Performance', async ({ page, context, request, browserName, isMobile }) => {
|
|
if (isMobile) return
|
|
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
await perfSuite.setupHeavyBoard()
|
|
|
|
testOutput(await perfSuite.testCanvasZooming())
|
|
})
|
|
|
|
test('Text Shape Creation Performance', async ({
|
|
page,
|
|
context,
|
|
request,
|
|
browserName,
|
|
isMobile,
|
|
}) => {
|
|
if (isMobile) return
|
|
|
|
// The scenario creates its own text shapes, so no heavy board is needed.
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
|
|
testOutput(await perfSuite.testTextShapeCreation())
|
|
})
|
|
})
|
|
|
|
test.describe('Baseline Management', () => {
|
|
test.skip('Establish All Performance Baselines', async ({
|
|
page,
|
|
context,
|
|
request,
|
|
browserName,
|
|
}) => {
|
|
test.setTimeout(120000) // 2 minutes for establishing all baselines
|
|
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
|
|
// This will run all performance tests and establish baselines
|
|
await perfSuite.establishBaselines()
|
|
|
|
// Verify baselines were created
|
|
const rotateBaseline = perfSuite.getBaseline('rotate_shapes')
|
|
const dragBaseline = perfSuite.getBaseline('drag_shapes')
|
|
const resizeBaseline = perfSuite.getBaseline('resize_shapes')
|
|
const panBaseline = perfSuite.getBaseline('canvas_panning')
|
|
const zoomBaseline = perfSuite.getBaseline('canvas_zooming')
|
|
|
|
expect(rotateBaseline).toBeTruthy()
|
|
expect(dragBaseline).toBeTruthy()
|
|
expect(resizeBaseline).toBeTruthy()
|
|
expect(panBaseline).toBeTruthy()
|
|
expect(zoomBaseline).toBeTruthy()
|
|
|
|
// eslint-disable-next-line no-console
|
|
console.log('✅ All baselines established successfully!')
|
|
})
|
|
|
|
test.skip('Manual Baseline Update Example', async ({ page, context, request, browserName }) => {
|
|
const perfSuite = await setupPerformanceTest({ page, context, request }, browserName)
|
|
await perfSuite.setupHeavyBoard()
|
|
|
|
const result = await perfSuite.testShapeRotation()
|
|
|
|
// Example of manually updating baseline (use with caution)
|
|
const existingBaseline = perfSuite.getBaseline('rotate_shapes')
|
|
if (!existingBaseline || result.metrics.averageFps > existingBaseline.avgFps) {
|
|
perfSuite.updateBaseline('rotate_shapes', result.metrics, true)
|
|
// eslint-disable-next-line no-console
|
|
console.log(`📊 Baseline updated: ${result.metrics.averageFps} FPS`)
|
|
}
|
|
|
|
expect(result.comparison).toBeDefined()
|
|
})
|
|
})
|