/** * Public Browsing Load Test * * Simulates 100 concurrent users browsing public pages * Tests: * - Homepage * - About page * - Solutions page * - Portfolio list * - Blog list * - Contact page * * NFR4 Requirements: * - p95 response time < 500ms * - Error rate < 1% * - 100 concurrent users sustained for 2 minutes */ import { check, group } from 'k6'; import { SharedArray } from 'k6/data'; import { urls, thresholdGroups, config } from './lib/config.js'; import { PageHelper, thinkTime, pickRandom } from './lib/helpers.js'; // Test configuration export const options = { stages: config.stages.publicBrowsing, thresholds: thresholdGroups.public, ...config.requestOptions, }; // Page list to browse const publicPages = [ urls.home, urls.about, urls.solutions, urls.portfolio, urls.blog, urls.contact, ]; // Initialize page helper const pageHelper = new PageHelper(config.baseUrl); /** * Main test scenario */ export default function () { // Scenario 1: Browse homepage (most common) group('Browse Homepage', () => { pageHelper.loadPage(urls.home); thinkTime(2, 4); // 2-4 seconds thinking }); // Scenario 2: Browse random pages (weighted) group('Browse Random Pages', () => { // Browse 3-6 random pages const pageCount = Math.floor(Math.random() * 4) + 3; for (let i = 0; i < pageCount; i++) { const randomPage = pickRandom(publicPages); pageHelper.loadPage(randomPage); thinkTime(1, 3); // 1-3 seconds thinking } }); // Scenario 3: Navigate to contact (conversion intent) group('Navigate to Contact', () => { // 20% chance to visit contact page if (Math.random() < 0.2) { pageHelper.loadPage(urls.contact); thinkTime(3, 5); // More time on contact page } }); // Scenario 4: Deep dive into portfolio or blog group('Deep Dive', () => { // 30% chance to deep dive if (Math.random() < 0.3) { const section = Math.random() > 0.5 ? 'portfolio' : 'blog'; if (section === 'portfolio') { // Browse portfolio items pageHelper.loadPage(urls.portfolio); thinkTime(1, 2); // Note: In real scenario, we would click individual items // This requires parsing the page to get item URLs } else { // Browse blog posts pageHelper.loadPage(urls.blog); thinkTime(1, 2); // Note: In real scenario, we would click individual posts } } }); // Small think time before next iteration thinkTime(2, 5); } /** * Setup function - runs once before test */ export function setup() { console.log('=== Public Browsing Load Test ==='); console.log(`Target: ${config.baseUrl}`); console.log(`Pages to browse: ${publicPages.length}`); console.log('Starting test...'); } /** * Teardown function - runs once after test */ export function teardown(data) { console.log('=== Test Complete ==='); console.log('Check results above for:'); console.log('- p95 response time < 500ms'); console.log('- Error rate < 1%'); console.log('- 100 concurrent users sustained'); }