| 235 | } |
| 236 | |
| 237 | class BrowserSessionImpl implements BrowserSession { |
| 238 | private browser: Browser |
| 239 | private context: BrowserContext |
| 240 | private page: Page | null |
| 241 | constructor(browser: Browser, context: BrowserContext) { |
| 242 | this.browser = browser |
| 243 | this.context = context |
| 244 | this.page = null |
| 245 | } |
| 246 | |
| 247 | async close() { |
| 248 | if (this.page) { |
| 249 | await this.page.close() |
| 250 | } |
| 251 | await this.context.close() |
| 252 | await this.browser.close() |
| 253 | } |
| 254 | |
| 255 | async hardNavigation(metricName: string, url: string) { |
| 256 | this.page = this.page ?? (await this.context.newPage()) |
| 257 | |
| 258 | const page = this.page |
| 259 | await withRequestMetrics(metricName, page, async () => { |
| 260 | await measureTime(`${metricName}/start`) |
| 261 | const idle = networkIdle(page, 3000) |
| 262 | await page.goto(url, { |
| 263 | waitUntil: 'commit', |
| 264 | }) |
| 265 | await measureTime(`${metricName}/html`, { |
| 266 | relativeTo: `${metricName}/start`, |
| 267 | }) |
| 268 | await page.waitForLoadState('domcontentloaded') |
| 269 | await measureTime(`${metricName}/dom`, { |
| 270 | relativeTo: `${metricName}/start`, |
| 271 | }) |
| 272 | await page.waitForLoadState('load') |
| 273 | await measureTime(`${metricName}/load`, { |
| 274 | relativeTo: `${metricName}/start`, |
| 275 | }) |
| 276 | const offset = await idle |
| 277 | await measureTime(`${metricName}`, { |
| 278 | offset, |
| 279 | relativeTo: `${metricName}/start`, |
| 280 | }) |
| 281 | }) |
| 282 | return page |
| 283 | } |
| 284 | |
| 285 | async softNavigationByClick(metricName: string, selector: string) { |
| 286 | const page = this.page |
| 287 | if (!page) { |
| 288 | throw new Error( |
| 289 | 'softNavigationByClick() must be called after hardNavigation()' |
| 290 | ) |
| 291 | } |
| 292 | await withRequestMetrics(metricName, page, async () => { |
| 293 | await measureTime(`${metricName}/start`) |
| 294 | const firstResponse = new Promise<void>((resolve) => { |
nothing calls this directly
no outgoing calls
no test coverage detected