/
next-fixture.ts
77 lines (68 loc) · 1.98 KB
/
next-fixture.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import type { Page, TestInfo } from '@playwright/test'
import type { NextWorkerFixture, FetchHandler } from './next-worker-fixture'
import type { NextOptions } from './next-options'
import type { FetchHandlerResult } from '../proxy'
import { handleRoute } from './page-route'
import { reportFetch } from './report'
export interface NextFixture {
onFetch: (handler: FetchHandler) => void
}
class NextFixtureImpl implements NextFixture {
public readonly testId: string
private fetchHandlers: FetchHandler[] = []
constructor(
private testInfo: TestInfo,
private options: NextOptions,
private worker: NextWorkerFixture,
private page: Page
) {
this.testId = testInfo.testId
const testHeaders = {
'Next-Test-Proxy-Port': String(worker.proxyPort),
'Next-Test-Data': this.testId,
}
const handleFetch = this.handleFetch.bind(this)
worker.onFetch(this.testId, handleFetch)
this.page.route('**', (route) =>
handleRoute(route, page, testHeaders, handleFetch)
)
}
teardown(): void {
this.worker.cleanupTest(this.testId)
}
onFetch(handler: FetchHandler): void {
this.fetchHandlers.push(handler)
}
private async handleFetch(request: Request): Promise<FetchHandlerResult> {
return reportFetch(this.testInfo, request, async (req) => {
for (const handler of this.fetchHandlers.slice().reverse()) {
const result = await handler(req.clone())
if (result) {
return result
}
}
if (this.options.fetchLoopback) {
return fetch(req.clone())
}
return undefined
})
}
}
export async function applyNextFixture(
use: (fixture: NextFixture) => Promise<void>,
{
testInfo,
nextOptions,
nextWorker,
page,
}: {
testInfo: TestInfo
nextOptions: NextOptions
nextWorker: NextWorkerFixture
page: Page
}
): Promise<void> {
const fixture = new NextFixtureImpl(testInfo, nextOptions, nextWorker, page)
await use(fixture)
fixture.teardown()
}