[READ-ONLY] a fast, modern browser for the npm registry
at main 151 lines 4.4 kB view raw
1/** 2 * Playwright fixtures for connector E2E tests. Extends test-utils.ts 3 * (which includes external API mocking) with connector-specific helpers. 4 */ 5 6import { test as base } from '../test-utils' 7import { DEFAULT_MOCK_CONFIG } from './mock-connector' 8 9const TEST_TOKEN = DEFAULT_MOCK_CONFIG.token 10const TEST_PORT = DEFAULT_MOCK_CONFIG.port ?? 31415 11 12/** 13 * Helper to make requests to the mock connector server. 14 * This allows tests to set up state before running. 15 */ 16export class MockConnectorClient { 17 private token: string 18 private baseUrl: string 19 20 constructor(token: string, port: number) { 21 this.token = token 22 this.baseUrl = `http://127.0.0.1:${port}` 23 } 24 25 private async request<T>(path: string, options?: RequestInit): Promise<T> { 26 const response = await fetch(`${this.baseUrl}${path}`, { 27 ...options, 28 headers: { 29 'Content-Type': 'application/json', 30 'Authorization': `Bearer ${this.token}`, 31 ...options?.headers, 32 }, 33 }) 34 if (!response.ok) { 35 throw new Error( 36 `Mock connector request failed: ${response.status} ${response.statusText} (${path})`, 37 ) 38 } 39 return response.json() as Promise<T> 40 } 41 42 private async testEndpoint(path: string, body: unknown): Promise<void> { 43 const response = await fetch(`${this.baseUrl}${path}`, { 44 method: 'POST', 45 headers: { 'Content-Type': 'application/json' }, 46 body: JSON.stringify(body), 47 }) 48 if (!response.ok) { 49 throw new Error( 50 `Mock connector test endpoint failed: ${response.status} ${response.statusText} (${path})`, 51 ) 52 } 53 } 54 55 async reset(): Promise<void> { 56 await this.testEndpoint('/__test__/reset', {}) 57 await this.testEndpoint('/connect', { token: this.token }) 58 } 59 60 async setOrgData( 61 org: string, 62 data: { 63 users?: Record<string, 'developer' | 'admin' | 'owner'> 64 teams?: string[] 65 teamMembers?: Record<string, string[]> 66 }, 67 ): Promise<void> { 68 await this.testEndpoint('/__test__/org', { org, ...data }) 69 } 70 71 async setUserOrgs(orgs: string[]): Promise<void> { 72 await this.testEndpoint('/__test__/user-orgs', { orgs }) 73 } 74 75 async setUserPackages(packages: Record<string, 'read-only' | 'read-write'>): Promise<void> { 76 await this.testEndpoint('/__test__/user-packages', { packages }) 77 } 78 79 async setPackageData( 80 pkg: string, 81 data: { collaborators?: Record<string, 'read-only' | 'read-write'> }, 82 ): Promise<void> { 83 await this.testEndpoint('/__test__/package', { package: pkg, ...data }) 84 } 85 86 async addOperation(operation: { 87 type: string 88 params: Record<string, string> 89 description: string 90 command: string 91 dependsOn?: string 92 }): Promise<{ id: string; status: string }> { 93 const result = await this.request<{ success: boolean; data: { id: string; status: string } }>( 94 '/operations', 95 { 96 method: 'POST', 97 body: JSON.stringify(operation), 98 }, 99 ) 100 return result.data 101 } 102 103 async getOperations(): Promise< 104 Array<{ id: string; type: string; status: string; params: Record<string, string> }> 105 > { 106 const result = await this.request<{ 107 success: boolean 108 data: { 109 operations: Array<{ 110 id: string 111 type: string 112 status: string 113 params: Record<string, string> 114 }> 115 } 116 }>('/state') 117 return result.data.operations 118 } 119} 120 121export interface ConnectorFixtures { 122 mockConnector: MockConnectorClient 123 testToken: string 124 connectorPort: number 125 /** Navigate to a page pre-authenticated with connector credentials. */ 126 gotoConnected: (path: string) => Promise<void> 127} 128 129export const test = base.extend<ConnectorFixtures>({ 130 mockConnector: async ({ page: _ }, use) => { 131 const client = new MockConnectorClient(TEST_TOKEN, TEST_PORT) 132 await client.reset() 133 await use(client) 134 }, 135 136 testToken: TEST_TOKEN, 137 138 connectorPort: TEST_PORT, 139 140 gotoConnected: async ({ goto, testToken, connectorPort }, use) => { 141 const navigateConnected = async (path: string) => { 142 const cleanPath = path.startsWith('/') ? path : `/${path}` 143 const separator = cleanPath.includes('?') ? '&' : '?' 144 const urlWithParams = `${cleanPath}${separator}token=${testToken}&port=${connectorPort}` 145 await goto(urlWithParams, { waitUntil: 'networkidle' }) 146 } 147 await use(navigateConnected) 148 }, 149}) 150 151export { expect } from '@nuxt/test-utils/playwright'