Last active
April 8, 2025 13:41
-
-
Save wellwind/ccf2abb3208e15e4638861da9eb163e7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { browser, Page } from 'k6/browser'; | |
import { check } from 'k6'; | |
import { Trend } from 'k6/metrics'; | |
// --- Options Configuration --- | |
export const options = { | |
scenarios: { | |
ui_testing: { | |
executor: 'per-vu-iterations', // Specify the executor type | |
vus: 3, | |
iterations: 5, | |
options: { | |
browser: { | |
type: 'chromium', | |
}, | |
}, | |
}, | |
}, | |
// Thresholds - Automatic PASS/FAIL determination for test results | |
thresholds: { | |
checks: ['rate==1.0'], // All checks must pass | |
step1_goto_duration: ['p(95)<=2000'], // 95th percentile of step 1 duration <= 2000ms | |
step2_click_duration: ['p(95)<=500'], // 95th percentile of step 2 duration <= 500ms | |
step3_check_tag_duration: ['p(95)<=500'], // 95th percentile of step 3 duration <= 500ms | |
browser_web_vital_ttfb: ['p(95) < 1000'], // 95th percentile of TTFB < 1000ms | |
}, | |
}; | |
// --- Custom Time Series Metrics (Trends) --- | |
// Create Trend metrics to track the duration of each step | |
const gotoTiming = new Trend('step1_goto_duration', true); | |
const clickTiming = new Trend('step2_click_duration', true); | |
const checkTagTiming = new Trend('step3_check_tag_duration', true); | |
/** | |
* BasePage class that provides common functionality for all page objects | |
*/ | |
class BasePage { | |
protected page: Page; | |
protected vu: number; | |
protected iter: number; | |
constructor(page: Page, vu: number, iter: number) { | |
this.page = page; | |
this.vu = vu; | |
this.iter = iter; | |
} | |
/** | |
* Logs a message with the current VU and iteration context | |
*/ | |
protected log(message: string): void { | |
console.log(`VU ${this.vu}, Iter ${this.iter}: ${message}`); | |
} | |
/** | |
* Logs an error with the current VU and iteration context | |
*/ | |
protected logError(message: string): void { | |
console.error(`VU ${this.vu}, Iter ${this.iter}: ${message}`); | |
} | |
/** | |
* Measures a performance operation with proper error handling | |
* @param operationName Name of the operation (used for performance marks) | |
* @param operation The async function to measure | |
* @param timingMetric The trend metric to record the timing | |
* @param fallbackDuration Duration to use if timing fails but operation succeeds | |
* @param timeoutDuration Duration to use if operation fails | |
*/ | |
protected async measureOperation( | |
operationName: string, | |
operation: () => Promise<void>, | |
timingMetric: Trend, | |
fallbackDuration: number, | |
timeoutDuration: number, | |
): Promise<boolean> { | |
let success = false; | |
try { | |
// Set start mark with error handling | |
try { | |
await this.page.evaluate( | |
(name) => window.performance.mark(`${name}_start`), | |
operationName, | |
); | |
} catch (markError) { | |
this.log( | |
`Unable to set ${operationName} start mark: ${markError.message}`, | |
); | |
} | |
// Execute the operation | |
await operation(); | |
// Try to measure the performance | |
let duration; | |
try { | |
await this.page.evaluate( | |
(name) => window.performance.mark(`${name}_end`), | |
operationName, | |
); | |
await this.page.evaluate( | |
(name) => | |
window.performance.measure( | |
`${name}_duration`, | |
`${name}_start`, | |
`${name}_end`, | |
), | |
operationName, | |
); | |
duration = await this.page.evaluate((name) => { | |
const entries = window.performance.getEntriesByName( | |
`${name}_duration`, | |
); | |
if (entries && entries.length > 0) { | |
return entries[0].duration; | |
} | |
return null; | |
}, operationName); | |
} catch (timingError) { | |
this.log( | |
`${operationName} performance timing failed: ${timingError.message}`, | |
); | |
} | |
// Use the measured duration or fallback to a reasonable estimate | |
if (duration) { | |
timingMetric.add(duration); | |
} else { | |
timingMetric.add(fallbackDuration); | |
} | |
success = true; | |
} catch (e) { | |
// Use timeout duration for failures | |
timingMetric.add(timeoutDuration); | |
this.logError( | |
`${operationName} FAILED: ${e ? e.message : 'Unknown error'}`, | |
); | |
} | |
return success; | |
} | |
} | |
/** | |
* BlogPage represents the blog homepage and its interactions | |
*/ | |
class BlogPage extends BasePage { | |
// Page URL | |
private readonly url = 'https://fullstackladder.dev/blog/'; | |
constructor(page: Page, vu: number, iter: number) { | |
super(page, vu, iter); | |
} | |
/** | |
* Navigate to the blog page | |
*/ | |
async navigateTo(): Promise<boolean> { | |
this.log('Step 1 - Navigating to blog page'); | |
const success = await this.measureOperation( | |
'step1', | |
async () => { | |
// Set navigation timeout | |
this.page.setDefaultNavigationTimeout(30000); | |
await this.page.goto(this.url, { | |
waitUntil: 'domcontentloaded', | |
}); | |
}, | |
gotoTiming, | |
1000, // Fallback duration if timing fails but operation succeeds | |
30000, // Timeout duration for failures | |
); | |
if (success) { | |
this.log('Step 1 - Navigation successful'); | |
} | |
check(success, { 'Step 1: Page loaded successfully': (s) => s }); | |
return success; | |
} | |
/** | |
* Click on the Tags link in the navigation | |
*/ | |
async clickTagsLink(): Promise<boolean> { | |
this.log("Step 2 - Finding and clicking the 'Tags' link"); | |
const success = await this.measureOperation( | |
'step2', | |
async () => { | |
// Use XPath locator to find the <a> element containing <span class="link-text">標籤</span> | |
const linkLocator = this.page.locator( | |
'//a[.//span[@class="link-text" and normalize-space()="標籤"]]', | |
); | |
// Click the element with an operation timeout | |
await linkLocator.click({ timeout: 1000 }); | |
}, | |
clickTiming, | |
500, // Fallback duration if timing fails but operation succeeds | |
1000, // Timeout duration for failures | |
); | |
if (success) { | |
this.log('Step 2 - Click successful'); | |
} | |
check(success, { 'Step 2: Successfully clicked "Tags" link': (s) => s }); | |
return success; | |
} | |
/** | |
* Verify that the blog tags element is visible | |
*/ | |
async verifyTagsElementVisible(): Promise<boolean> { | |
this.log("Step 3 - Verifying 'app-blog-tags' element exists"); | |
const success = await this.measureOperation( | |
'step3', | |
async () => { | |
await this.page | |
.locator('app-blog-tags') | |
.waitFor({ state: 'visible', timeout: 2000 }); | |
}, | |
checkTagTiming, | |
200, // Fallback duration if timing fails but operation succeeds | |
2000, // Timeout duration for failures | |
); | |
if (success) { | |
this.log("Step 3 - Element 'app-blog-tags' is visible"); | |
} | |
check(success, { 'Step 3: app-blog-tags element is visible': (s) => s }); | |
return success; | |
} | |
} | |
// --- Main Test Logic (default function) --- | |
export default async function () { | |
// Create a new browser page for each iteration of each VU | |
const page = await browser.newPage(); | |
// Set default timeout for page operations (ms) to prevent hangs | |
page.setDefaultTimeout(30000); | |
page.setDefaultNavigationTimeout(30000); | |
const vu = __VU; // Virtual User ID | |
const iter = __ITER; // Iteration number for the current VU | |
console.log(`VU ${vu}, Iter ${iter}: Starting iteration`); | |
try { | |
// Create blog page object | |
const blogPage = new BlogPage(page, vu, iter); | |
let stepSuccess: boolean; | |
// Step 1: Navigate to blog page | |
stepSuccess = await blogPage.navigateTo(); | |
if (!stepSuccess) throw new Error('Step 1 Failed, stopping iteration'); | |
// Step 2: Click on tags link | |
stepSuccess = await blogPage.clickTagsLink(); | |
if (!stepSuccess) throw new Error('Step 2 Failed, stopping iteration'); | |
// Step 3: Verify tags element is visible | |
stepSuccess = await blogPage.verifyTagsElementVisible(); | |
if (!stepSuccess) throw new Error('Step 3 Failed, stopping iteration'); | |
console.log(`VU ${vu}, Iter ${iter}: Iteration finished successfully`); | |
} catch (err: any) { | |
// Catch errors thrown from steps | |
console.error( | |
`VU ${vu}, Iter ${iter}: Iteration aborted due to error: ${err.message}`, | |
); | |
// Optionally record a failed check if the iteration is aborted | |
check(false, { 'Iteration Overall Success': (ok) => ok }); | |
} finally { | |
// --- Cleanup: Close the page regardless of success or failure --- | |
await page.close(); | |
console.log(`VU ${vu}, Iter ${iter}: Page closed`); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/\ Grafana /‾‾/ | |
/\ / \ |\ __ / / | |
/ \/ \ | |/ / / ‾‾\ | |
/ \ | ( | (‾) | | |
/ __________ \ |_|\_\ \_____/ | |
execution: local | |
script: tag-cloud.k6.ts | |
output: - | |
scenarios: (100.00%) 1 scenario, 3 max VUs, 10m30s max duration (incl. graceful stop): | |
* ui_testing: 5 iterations for each of 3 VUs (maxDuration: 10m0s, gracefulStop: 30s) | |
INFO[0000] VU 3, Iter 0: Starting iteration source=console | |
INFO[0000] VU 3, Iter 0: Step 1 - Navigating to blog page source=console | |
INFO[0000] VU 2, Iter 0: Starting iteration source=console | |
INFO[0000] VU 2, Iter 0: Step 1 - Navigating to blog page source=console | |
INFO[0000] VU 1, Iter 0: Starting iteration source=console | |
INFO[0000] VU 1, Iter 0: Step 1 - Navigating to blog page source=console | |
INFO[0002] VU 2, Iter 0: step1 performance timing failed: undefined source=console | |
INFO[0002] VU 2, Iter 0: Step 1 - Navigation successful source=console | |
INFO[0002] VU 2, Iter 0: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0002] VU 2, Iter 0: Step 2 - Click successful source=console | |
INFO[0002] VU 2, Iter 0: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0003] VU 2, Iter 0: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0003] VU 2, Iter 0: Iteration finished successfully source=console | |
INFO[0003] VU 2, Iter 0: Page closed source=console | |
INFO[0003] VU 3, Iter 0: step1 performance timing failed: undefined source=console | |
INFO[0003] VU 3, Iter 0: Step 1 - Navigation successful source=console | |
INFO[0003] VU 3, Iter 0: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0003] VU 1, Iter 0: step1 performance timing failed: undefined source=console | |
INFO[0003] VU 1, Iter 0: Step 1 - Navigation successful source=console | |
INFO[0003] VU 1, Iter 0: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0003] VU 3, Iter 0: Step 2 - Click successful source=console | |
INFO[0003] VU 3, Iter 0: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0003] VU 2, Iter 1: Starting iteration source=console | |
INFO[0003] VU 2, Iter 1: Step 1 - Navigating to blog page source=console | |
INFO[0003] VU 1, Iter 0: Step 2 - Click successful source=console | |
INFO[0003] VU 1, Iter 0: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0004] VU 3, Iter 0: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0004] VU 3, Iter 0: Iteration finished successfully source=console | |
INFO[0004] VU 3, Iter 0: Page closed source=console | |
INFO[0004] VU 1, Iter 0: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0004] VU 1, Iter 0: Iteration finished successfully source=console | |
INFO[0004] VU 1, Iter 0: Page closed source=console | |
INFO[0004] VU 3, Iter 1: Starting iteration source=console | |
INFO[0004] VU 3, Iter 1: Step 1 - Navigating to blog page source=console | |
INFO[0005] VU 1, Iter 1: Starting iteration source=console | |
INFO[0005] VU 1, Iter 1: Step 1 - Navigating to blog page source=console | |
INFO[0005] VU 2, Iter 1: step1 performance timing failed: undefined source=console | |
INFO[0005] VU 2, Iter 1: Step 1 - Navigation successful source=console | |
INFO[0005] VU 2, Iter 1: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0005] VU 2, Iter 1: Step 2 - Click successful source=console | |
INFO[0005] VU 2, Iter 1: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0005] VU 2, Iter 1: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0005] VU 2, Iter 1: Iteration finished successfully source=console | |
INFO[0006] VU 2, Iter 1: Page closed source=console | |
INFO[0006] VU 3, Iter 1: step1 performance timing failed: undefined source=console | |
INFO[0006] VU 3, Iter 1: Step 1 - Navigation successful source=console | |
INFO[0006] VU 3, Iter 1: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0006] VU 1, Iter 1: step1 performance timing failed: undefined source=console | |
INFO[0006] VU 1, Iter 1: Step 1 - Navigation successful source=console | |
INFO[0006] VU 1, Iter 1: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0006] VU 2, Iter 2: Starting iteration source=console | |
INFO[0006] VU 2, Iter 2: Step 1 - Navigating to blog page source=console | |
INFO[0006] VU 3, Iter 1: Step 2 - Click successful source=console | |
INFO[0006] VU 3, Iter 1: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0006] VU 1, Iter 1: Step 2 - Click successful source=console | |
INFO[0006] VU 1, Iter 1: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0007] VU 3, Iter 1: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0007] VU 3, Iter 1: Iteration finished successfully source=console | |
INFO[0007] VU 3, Iter 1: Page closed source=console | |
INFO[0007] VU 1, Iter 1: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0007] VU 1, Iter 1: Iteration finished successfully source=console | |
INFO[0007] VU 1, Iter 1: Page closed source=console | |
INFO[0007] VU 3, Iter 2: Starting iteration source=console | |
INFO[0007] VU 3, Iter 2: Step 1 - Navigating to blog page source=console | |
INFO[0008] VU 1, Iter 2: Starting iteration source=console | |
INFO[0008] VU 1, Iter 2: Step 1 - Navigating to blog page source=console | |
INFO[0008] VU 2, Iter 2: step1 performance timing failed: undefined source=console | |
INFO[0008] VU 2, Iter 2: Step 1 - Navigation successful source=console | |
INFO[0008] VU 2, Iter 2: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0008] VU 2, Iter 2: Step 2 - Click successful source=console | |
INFO[0008] VU 2, Iter 2: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0009] VU 2, Iter 2: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0009] VU 2, Iter 2: Iteration finished successfully source=console | |
INFO[0009] VU 2, Iter 2: Page closed source=console | |
INFO[0009] VU 3, Iter 2: step1 performance timing failed: undefined source=console | |
INFO[0009] VU 3, Iter 2: Step 1 - Navigation successful source=console | |
INFO[0009] VU 3, Iter 2: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0009] VU 1, Iter 2: step1 performance timing failed: undefined source=console | |
INFO[0009] VU 1, Iter 2: Step 1 - Navigation successful source=console | |
INFO[0009] VU 1, Iter 2: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0009] VU 2, Iter 3: Starting iteration source=console | |
INFO[0009] VU 2, Iter 3: Step 1 - Navigating to blog page source=console | |
INFO[0009] VU 3, Iter 2: Step 2 - Click successful source=console | |
INFO[0009] VU 3, Iter 2: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0010] VU 1, Iter 2: Step 2 - Click successful source=console | |
INFO[0010] VU 1, Iter 2: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0010] VU 3, Iter 2: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0010] VU 3, Iter 2: Iteration finished successfully source=console | |
INFO[0010] VU 3, Iter 2: Page closed source=console | |
INFO[0010] VU 1, Iter 2: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0010] VU 1, Iter 2: Iteration finished successfully source=console | |
INFO[0010] VU 1, Iter 2: Page closed source=console | |
INFO[0011] VU 3, Iter 3: Starting iteration source=console | |
INFO[0011] VU 3, Iter 3: Step 1 - Navigating to blog page source=console | |
INFO[0011] VU 1, Iter 3: Starting iteration source=console | |
INFO[0011] VU 1, Iter 3: Step 1 - Navigating to blog page source=console | |
INFO[0011] VU 2, Iter 3: step1 performance timing failed: undefined source=console | |
INFO[0011] VU 2, Iter 3: Step 1 - Navigation successful source=console | |
INFO[0011] VU 2, Iter 3: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0011] VU 2, Iter 3: Step 2 - Click successful source=console | |
INFO[0011] VU 2, Iter 3: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0012] VU 2, Iter 3: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0012] VU 2, Iter 3: Iteration finished successfully source=console | |
INFO[0012] VU 2, Iter 3: Page closed source=console | |
INFO[0012] VU 3, Iter 3: step1 performance timing failed: undefined source=console | |
INFO[0012] VU 3, Iter 3: Step 1 - Navigation successful source=console | |
INFO[0012] VU 3, Iter 3: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0012] VU 1, Iter 3: step1 performance timing failed: undefined source=console | |
INFO[0012] VU 1, Iter 3: Step 1 - Navigation successful source=console | |
INFO[0012] VU 1, Iter 3: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0012] VU 2, Iter 4: Starting iteration source=console | |
INFO[0012] VU 2, Iter 4: Step 1 - Navigating to blog page source=console | |
INFO[0012] VU 3, Iter 3: Step 2 - Click successful source=console | |
INFO[0012] VU 3, Iter 3: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0013] VU 1, Iter 3: Step 2 - Click successful source=console | |
INFO[0013] VU 1, Iter 3: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0013] VU 3, Iter 3: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0013] VU 3, Iter 3: Iteration finished successfully source=console | |
INFO[0013] VU 3, Iter 3: Page closed source=console | |
INFO[0013] VU 1, Iter 3: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0013] VU 1, Iter 3: Iteration finished successfully source=console | |
INFO[0013] VU 1, Iter 3: Page closed source=console | |
INFO[0014] VU 3, Iter 4: Starting iteration source=console | |
INFO[0014] VU 3, Iter 4: Step 1 - Navigating to blog page source=console | |
INFO[0014] VU 2, Iter 4: step1 performance timing failed: undefined source=console | |
INFO[0014] VU 2, Iter 4: Step 1 - Navigation successful source=console | |
INFO[0014] VU 2, Iter 4: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0014] VU 1, Iter 4: Starting iteration source=console | |
INFO[0014] VU 1, Iter 4: Step 1 - Navigating to blog page source=console | |
INFO[0014] VU 2, Iter 4: Step 2 - Click successful source=console | |
INFO[0014] VU 2, Iter 4: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0015] VU 2, Iter 4: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0015] VU 2, Iter 4: Iteration finished successfully source=console | |
INFO[0015] VU 2, Iter 4: Page closed source=console | |
INFO[0015] VU 3, Iter 4: step1 performance timing failed: undefined source=console | |
INFO[0015] VU 3, Iter 4: Step 1 - Navigation successful source=console | |
INFO[0015] VU 3, Iter 4: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0015] VU 1, Iter 4: step1 performance timing failed: undefined source=console | |
INFO[0015] VU 1, Iter 4: Step 1 - Navigation successful source=console | |
INFO[0015] VU 1, Iter 4: Step 2 - Finding and clicking the 'Tags' link source=console | |
INFO[0015] VU 3, Iter 4: Step 2 - Click successful source=console | |
INFO[0015] VU 3, Iter 4: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0016] VU 1, Iter 4: Step 2 - Click successful source=console | |
INFO[0016] VU 1, Iter 4: Step 3 - Verifying 'app-blog-tags' element exists source=console | |
INFO[0016] VU 3, Iter 4: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0016] VU 3, Iter 4: Iteration finished successfully source=console | |
INFO[0016] VU 3, Iter 4: Page closed source=console | |
INFO[0016] VU 1, Iter 4: Step 3 - Element 'app-blog-tags' is visible source=console | |
INFO[0016] VU 1, Iter 4: Iteration finished successfully source=console | |
INFO[0016] VU 1, Iter 4: Page closed source=console | |
█ THRESHOLDS | |
browser_web_vital_ttfb | |
✓ 'p(95) < 1000' p(95)=509.27ms | |
checks | |
✓ 'rate==1.0' rate=100.00% | |
step1_goto_duration | |
✓ 'p(95)<=2000' p(95)=1s | |
step2_click_duration | |
✓ 'p(95)<=500' p(95)=328.24ms | |
step3_check_tag_duration | |
✓ 'p(95)<=500' p(95)=279.34ms | |
█ TOTAL RESULTS | |
checks_total.......................: 45 2.714756/s | |
checks_succeeded...................: 100.00% 45 out of 45 | |
checks_failed......................: 0.00% 0 out of 45 | |
✓ Step 1: Page loaded successfully | |
✓ Step 2: Successfully clicked "Tags" link | |
✓ Step 3: app-blog-tags element is visible | |
CUSTOM | |
step1_goto_duration..................................: avg=1s min=1s med=1s max=1s p(90)=1s p(95)=1s | |
step2_click_duration.................................: avg=311.08ms min=300.59ms med=309.2ms max=339.09ms p(90)=320.11ms p(95)=328.24ms | |
step3_check_tag_duration.............................: avg=226.53ms min=205.8ms med=214.5ms max=387ms p(90)=230.64ms p(95)=279.34ms | |
EXECUTION | |
iteration_duration...................................: avg=2.68s min=2.21s med=2.55s max=3.68s p(90)=3.22s p(95)=3.55s | |
iterations...........................................: 15 0.904919/s | |
vus..................................................: 2 min=2 max=3 | |
vus_max..............................................: 3 min=3 max=3 | |
NETWORK | |
data_received........................................: 0 B 0 B/s | |
data_sent............................................: 0 B 0 B/s | |
BROWSER | |
browser_data_received................................: 38 MB 2.3 MB/s | |
browser_data_sent....................................: 343 kB 21 kB/s | |
browser_http_req_duration............................: avg=242.69ms min=468µs med=167.25ms max=1.63s p(90)=457.22ms p(95)=504.16ms | |
browser_http_req_failed..............................: 0.00% 0 out of 648 | |
WEB_VITALS | |
browser_web_vital_cls................................: avg=0.000797 min=0.000797 med=0.000797 max=0.000797 p(90)=0.000797 p(95)=0.000797 | |
browser_web_vital_fcp................................: avg=691.73ms min=568ms med=700ms max=840ms p(90)=745.6ms p(95)=778.4ms | |
browser_web_vital_fid................................: avg=273.33µs min=199.99µs med=299.99µs max=400µs p(90)=359.99µs p(95)=399.99µs | |
browser_web_vital_inp................................: avg=36.26ms min=32ms med=32ms max=56ms p(90)=40ms p(95)=44.79ms | |
browser_web_vital_lcp................................: avg=1.38s min=968ms med=1.22s max=2.4s p(90)=1.9s p(95)=2.28s | |
browser_web_vital_ttfb...............................: avg=369.46ms min=326.09ms med=348ms max=600.9ms p(90)=427.24ms p(95)=509.27ms | |
running (00m16.6s), 0/3 VUs, 15 complete and 0 interrupted iterations | |
ui_testing ✓ [======================================] 3 VUs 00m16.6s/10m0s 15/15 iters, 5 per VU |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment