8const pollForException = async ({nonce, timeoutMs = 60000, intervalMs = 5000}: {nonce: string, timeoutMs?: number, intervalMs?: number}) => { 9 const startTime = Date.now() 11 while (Date.now() - startTime < timeoutMs) { 13 console.log(` poll #${pollCount}...`) 14 const exceptions = await fetchExceptions({limit: 20, includeBody: true, isTest: true}) 15 for (const exc of exceptions) { 16 const gpTestNonce = exc.pterrJson?.uniqDebugH?.gpTestNonce as string | undefined 17 if (gpTestNonce === nonce || exc.bodyRaw.includes(nonce)) { 18 console.log(` found: ${exc.subject}`) 19 return {found: true, exception: exc} 24 return {found: false, exception: null} 27export const runSendRecvExceptionSuite = async ({baseUrl, ptenv, singleTestName, doFetch = gqlFetch}: {baseUrl: string, ptenv: Ptenv, singleTestName?: string, doFetch?: typeof gqlFetch}) => { 28 if (ptenv === ptenvLocal) return skipSuite('skipped on local (use --ptenv=testprod)') 32 test('serverException', async () => { 34 if (!exceptionTrigger) return {passed: false, msg: 'appSecret not available, cannot get exception trigger'} 36 const gpTestNonce = `xtest${Date.now()}` 37 console.log(` nonce: ${gpTestNonce}`) 39 const mutationGql = `mutation($gpVersion: String, $gpTestNonce: String) { gmGenTestGqlException(gpVersion: $gpVersion, gpTestNonce: $gpTestNonce) }` 40 const gqlResult = await doFetch({baseUrl, query: mutationGql, variables: {gpVersion: exceptionTrigger, gpTestNonce}}) 41 if (!(gqlResult?.errors?.length > 0)) return {passed: false, msg: 'mutation did not throw (trigger may not match)'} 43 const {found, exception} = await pollForException({nonce: gpTestNonce, timeoutMs: 60000}) 44 return {passed: found, msg: found ? `${exception?.errHash} (${exception?.date.toISOString()})` : `email with nonce "${gpTestNonce}" not received within 60s`} 47 test('clientJsError', async () => { 48 const gpTestNonce = `jstest${Date.now()}` 49 console.log(` nonce: ${gpTestNonce}`) 51 const mutationGql = `mutation($gpJsErrJson: JsErrInputGqt!) { gmReportJsErr(gpJsErrJson: $gpJsErrJson) }` 53 gpErrMsg: `Test JS error ${gpTestNonce}`, 54 gpErrStackS: `Error: Test JS error ${gpTestNonce}\n at TestComponent (test.js:1:1)`, 55 gpErrCompStackS: ' at TestComponent\n at App', 56 gpUrl: '/test-page?nonce=' + gpTestNonce, 58 const gqlResult = await doFetch({baseUrl, query: mutationGql, variables: {gpJsErrJson}}) 59 if (gqlResult?.errors?.length > 0) return {passed: false, msg: 'gmReportJsErr returned errors: ' + gqlResult.errors[0]?.message} 60 if (gqlResult?.data?.gmReportJsErr !== 'ok') return {passed: false, msg: 'gmReportJsErr did not return ok (might be isDevPc returning true)'} 62 const {found, exception} = await pollForException({nonce: gpTestNonce, timeoutMs: 60000}) 63 return {passed: found, msg: found ? `${exception?.errHash} (${exception?.date.toISOString()})` : `email with nonce "${gpTestNonce}" not received within 60s`}