1
0
forked from baron/baron-sso

userfront e2e 전체 테스트

This commit is contained in:
2026-05-29 08:19:34 +09:00
parent dc16958804
commit da01f63c54
22 changed files with 1439 additions and 103 deletions

View File

@@ -1,6 +1,14 @@
import { devices, expect, test, type Page, type Request } from '@playwright/test';
import {
devices,
expect,
test,
type Page,
type Request,
type Response,
} from '@playwright/test';
type LoadMetrics = {
appOrigin: string;
durationMs: number;
transferredBytes: number;
requestedUrls: string[];
@@ -30,6 +38,9 @@ async function mockPublicApis(page: Page): Promise<void> {
}
async function measureSigninLoad(page: Page): Promise<LoadMetrics> {
const appOrigin = new URL(
process.env.BASE_URL ?? `http://127.0.0.1:${process.env.PORT ?? '4173'}`,
).origin;
const requestedUrls: string[] = [];
const requestedPathCounts = new Map<string, number>();
const cacheControlByPath = new Map<string, string>();
@@ -48,7 +59,7 @@ async function measureSigninLoad(page: Page): Promise<LoadMetrics> {
}
};
const onResponse = async (response) => {
const onResponse = async (response: Response) => {
const url = new URL(response.url());
const cacheControl = response.headers()['cache-control'];
if (cacheControl) {
@@ -76,6 +87,7 @@ async function measureSigninLoad(page: Page): Promise<LoadMetrics> {
const durationMs = Math.round(performance.now() - start);
return {
appOrigin,
durationMs,
transferredBytes,
requestedUrls,
@@ -92,9 +104,11 @@ async function measureSigninLoad(page: Page): Promise<LoadMetrics> {
function expectNoDuplicateStaticRequests(metrics: LoadMetrics): void {
const duplicates = [...metrics.requestedPathCounts.entries()].filter(
([resourceKey, count]) => {
const path = new URL(resourceKey).pathname;
const resourceUrl = new URL(resourceKey);
const path = resourceUrl.pathname;
return (
count > 1 &&
resourceUrl.origin === metrics.appOrigin &&
!path.startsWith('/api/') &&
!path.endsWith('/ko/signin') &&
!path.endsWith('/') &&
@@ -112,12 +126,28 @@ function resolvePerformanceBudget(projectName: string): {
coldMs: number;
warmMs: number;
} {
if (projectName.includes('webkit')) {
return { coldMs: 4000, warmMs: 4000 };
}
if (projectName.includes('firefox')) {
return { coldMs: 2600, warmMs: 2800 };
}
if (projectName.includes('mobile')) {
return { coldMs: 3000, warmMs: 2300 };
}
return { coldMs: 2300, warmMs: 1500 };
}
function resolveRootRedirectBudget(projectName: string): number {
if (projectName.includes('webkit')) {
return 700;
}
if (projectName.includes('firefox')) {
return 600;
}
return 300;
}
test.describe('UserFront login performance budget', () => {
test('mobile Chrome service worker install does not fetch unused CanvasKit variants', async ({
browser,
@@ -222,7 +252,7 @@ test.describe('UserFront login performance budget', () => {
test('root redirects to localized signin before Flutter boots', async ({
page,
}) => {
}, testInfo) => {
await mockPublicApis(page);
const requestedUrls: string[] = [];
@@ -235,7 +265,9 @@ test.describe('UserFront login performance budget', () => {
await expect(page).toHaveURL(/\/ko\/signin(?:\?.*)?$/);
const durationMs = Math.round(performance.now() - start);
expect(durationMs).toBeLessThanOrEqual(300);
expect(durationMs).toBeLessThanOrEqual(
resolveRootRedirectBudget(testInfo.project.name),
);
const rootIndex = requestedUrls.findIndex(
(url) => new URL(url).pathname === '/',
);