@@ -24,7 +24,7 @@ import { activityStartedSignal } from './workflows/definitions';
2424import * as workflows from './workflows' ;
2525import { Context , createLocalTestEnvironment , helpers , makeTestFunction } from './helpers-integration' ;
2626import { overrideSdkInternalFlag } from './mock-internal-flags' ;
27- import { asSdkLoggerSink , loadHistory , RUN_TIME_SKIPPING_TESTS } from './helpers' ;
27+ import { asSdkLoggerSink , loadHistory , RUN_TIME_SKIPPING_TESTS , waitUntil } from './helpers' ;
2828
2929const test = makeTestFunction ( {
3030 workflowsPath : __filename ,
@@ -1337,3 +1337,78 @@ test('can register search attributes to dev server', async (t) => {
13371337 t . deepEqual ( desc . searchAttributes , { 'new-search-attr' : [ 12 ] } ) ; // eslint-disable-line deprecation/deprecation
13381338 await env . teardown ( ) ;
13391339} ) ;
1340+
1341+ export async function ChildWorkflowInfo ( ) : Promise < workflow . RootWorkflowInfo | undefined > {
1342+ let blocked = true ;
1343+ workflow . setHandler ( unblockSignal , ( ) => {
1344+ blocked = false ;
1345+ } ) ;
1346+ await workflow . condition ( ( ) => ! blocked ) ;
1347+ return workflow . workflowInfo ( ) . root ;
1348+ }
1349+
1350+ export async function WithChildWorkflow ( childWfId : string ) : Promise < workflow . RootWorkflowInfo | undefined > {
1351+ return await workflow . executeChild ( ChildWorkflowInfo , {
1352+ workflowId : childWfId ,
1353+ } ) ;
1354+ }
1355+
1356+ test ( 'root execution is exposed' , async ( t ) => {
1357+ const { createWorker, startWorkflow } = helpers ( t ) ;
1358+ const worker = await createWorker ( ) ;
1359+
1360+ await worker . runUntil ( async ( ) => {
1361+ const childWfId = 'child-wf-id' ;
1362+ const handle = await startWorkflow ( WithChildWorkflow , {
1363+ args : [ childWfId ] ,
1364+ } ) ;
1365+
1366+ const childHandle = t . context . env . client . workflow . getHandle ( childWfId ) ;
1367+ const childStarted = async ( ) : Promise < boolean > => {
1368+ try {
1369+ await childHandle . describe ( ) ;
1370+ return true ;
1371+ } catch ( e ) {
1372+ if ( e instanceof workflow . WorkflowNotFoundError ) {
1373+ return false ;
1374+ } else {
1375+ throw e ;
1376+ }
1377+ }
1378+ } ;
1379+ await waitUntil ( childStarted , 5000 ) ;
1380+ const childDesc = await childHandle . describe ( ) ;
1381+ const parentDesc = await handle . describe ( ) ;
1382+
1383+ t . true ( childDesc . rootExecution ?. workflowId === parentDesc . workflowId ) ;
1384+ t . true ( childDesc . rootExecution ?. runId === parentDesc . runId ) ;
1385+
1386+ await childHandle . signal ( unblockSignal ) ;
1387+ const childWfInfoRoot = await handle . result ( ) ;
1388+ t . true ( childWfInfoRoot ?. workflowId === parentDesc . workflowId ) ;
1389+ t . true ( childWfInfoRoot ?. runId === parentDesc . runId ) ;
1390+ } ) ;
1391+ } ) ;
1392+
1393+ export async function rootWorkflow ( ) : Promise < string > {
1394+ let result = '' ;
1395+ if ( ! workflow . workflowInfo ( ) . root ) {
1396+ result += 'empty' ;
1397+ } else {
1398+ result += workflow . workflowInfo ( ) . root ! . workflowId ;
1399+ }
1400+ if ( ! workflow . workflowInfo ( ) . parent ) {
1401+ result += ' ' ;
1402+ result += await workflow . executeChild ( rootWorkflow ) ;
1403+ }
1404+ return result ;
1405+ }
1406+
1407+ test ( 'Workflow can return root workflow' , async ( t ) => {
1408+ const { createWorker, executeWorkflow } = helpers ( t ) ;
1409+ const worker = await createWorker ( ) ;
1410+ await worker . runUntil ( async ( ) => {
1411+ const result = await executeWorkflow ( rootWorkflow , { workflowId : 'test-root-workflow-length' } ) ;
1412+ t . deepEqual ( result , 'empty test-root-workflow-length' ) ;
1413+ } ) ;
1414+ } ) ;
0 commit comments