| 1 |
import { request, test as baseTest } from '@playwright/test'; |
| 2 |
import fs from 'fs'; |
| 3 |
import path from 'path'; |
| 4 |
import { fetchNonce, login } from './wp-authentication'; |
| 5 |
import ApiRequests from './assets/api-requests'; |
| 6 |
|
| 7 |
export const parallelTest = baseTest.extend< NonNullable<unknown>, { workerStorageState: string, workerBaseURL: string, apiRequests: ApiRequests }>( { |
| 8 |
// Use the same storage state for all tests in this worker. |
| 9 |
baseURL: ( { workerBaseURL }, use ) => use( workerBaseURL ), |
| 10 |
workerBaseURL: [ async ( {}, use ) => { |
| 11 |
await use( process.env.BASE_URL || ( ( 1 === Number( process.env.TEST_PARALLEL_INDEX ) ) |
| 12 |
? process.env.TEST_SERVER |
| 13 |
: process.env.DEV_SERVER ), |
| 14 |
); |
| 15 |
}, { scope: 'worker' } ], |
| 16 |
|
| 17 |
// Use the same storage state for all tests in this worker. |
| 18 |
storageState: ( { workerStorageState }, use ) => use( workerStorageState ), |
| 19 |
|
| 20 |
// Authenticate once per worker with a worker-scoped fixture. |
| 21 |
workerStorageState: [ async ( { workerBaseURL }, use, testInfo ) => { |
| 22 |
// Use parallelIndex as a unique identifier for each worker. |
| 23 |
const id = testInfo.workerIndex; |
| 24 |
const fileName = path.resolve( testInfo.project.outputDir, `.storageState-${ id }.json` ); |
| 25 |
|
| 26 |
if ( fs.existsSync( fileName ) ) { |
| 27 |
// Reuse existing authentication state if any. |
| 28 |
await use( fileName ); |
| 29 |
return; |
| 30 |
} |
| 31 |
|
| 32 |
// Send authentication request. |
| 33 |
const context = await login( request, process.env.USERNAME || 'admin', process.env.PASSWORD || 'password', workerBaseURL ); |
| 34 |
await context.storageState( { path: fileName } ); |
| 35 |
await context.dispose(); |
| 36 |
|
| 37 |
await use( fileName ); |
| 38 |
}, { scope: 'worker' } ], |
| 39 |
|
| 40 |
// Use the same storage state for all tests in this worker. |
| 41 |
apiRequests: [ async ( { workerStorageState, workerBaseURL }, use ) => { |
| 42 |
const context = await request.newContext( { storageState: workerStorageState } ); |
| 43 |
try { |
| 44 |
const nonce = await fetchNonce( context, workerBaseURL ); |
| 45 |
const apiRequests = new ApiRequests( workerBaseURL, nonce ); |
| 46 |
await use( apiRequests ); |
| 47 |
} catch ( e ) { |
| 48 |
throw new Error( `Failed to fetch Nonce. Base URL: ${ workerBaseURL }, Storage State: ${ workerStorageState } `, { cause: e } ); |
| 49 |
} |
| 50 |
}, { scope: 'worker' } ], |
| 51 |
|
| 52 |
} ); |
| 53 |
|