diff --git a/src/apps/Elsa.Server.Web/Program.cs b/src/apps/Elsa.Server.Web/Program.cs
index 764309636..0fe6f4bca 100644
--- a/src/apps/Elsa.Server.Web/Program.cs
+++ b/src/apps/Elsa.Server.Web/Program.cs
@@ -69,7 +69,7 @@ const bool useKafka = false;
const bool useReadOnlyMode = false;
const bool useSignalR = false; // Disabled until Elsa Studio sends authenticated requests.
const WorkflowRuntime workflowRuntime = WorkflowRuntime.ProtoActor;
-const DistributedCachingTransport distributedCachingTransport = DistributedCachingTransport.MassTransit;
+const DistributedCachingTransport distributedCachingTransport = DistributedCachingTransport.ProtoActor;
const MassTransitBroker massTransitBroker = MassTransitBroker.Memory;
const bool useMultitenancy = false;
const bool useAgents = false;
diff --git a/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs b/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs
index 68b14ac0f..c813ada31 100644
--- a/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs
+++ b/src/modules/Elsa.Workflows.Core/Builders/WorkflowBuilder.cs
@@ -123,14 +123,7 @@ public class WorkflowBuilder(IActivityVisitor activityVisitor, IIdentityGraphSer
///
public InputDefinition WithInput(string name, string? description = default)
{
- return WithInput(inputDefinition =>
- {
- inputDefinition.Name = name;
- inputDefinition.Type = typeof(T);
-
- if (description != null)
- inputDefinition.Description = description;
- });
+ return WithInput(name, typeof(T), description);
}
///
@@ -173,6 +166,46 @@ public class WorkflowBuilder(IActivityVisitor activityVisitor, IIdentityGraphSer
return this;
}
+ public OutputDefinition WithOutput(string name, string? description = default)
+ {
+ return WithOutput(name, typeof(T), description);
+ }
+
+ public OutputDefinition WithOutput(string name, Type type, string? description = default)
+ {
+ return WithOutput(outputDefinition =>
+ {
+ outputDefinition.Name = name;
+ outputDefinition.Type = type;
+
+ if (description != null)
+ outputDefinition.Description = description;
+ });
+ }
+
+ public OutputDefinition WithOutput(string name, Type type, Action? setup = default)
+ {
+ return WithOutput(outputDefinition =>
+ {
+ outputDefinition.Name = name;
+ outputDefinition.Type = type;
+ setup?.Invoke(outputDefinition);
+ });
+ }
+
+ public OutputDefinition WithOutput(Action setup)
+ {
+ var outputDefinition = new OutputDefinition();
+ setup(outputDefinition);
+ return WithOutput(outputDefinition);
+ }
+
+ public OutputDefinition WithOutput(OutputDefinition outputDefinition)
+ {
+ Outputs.Add(outputDefinition);
+ return outputDefinition;
+ }
+
///
public IWorkflowBuilder WithCustomProperty(string name, object value)
{
diff --git a/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs b/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs
index 3272ec422..363fcbf11 100644
--- a/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs
+++ b/src/modules/Elsa.Workflows.Core/Contracts/IWorkflowBuilder.cs
@@ -156,6 +156,31 @@ public interface IWorkflowBuilder
/// A fluent method for adding an input to .
///
IWorkflowBuilder WithInput(InputDefinition inputDefinition);
+
+ ///
+ /// A fluent method for adding an output to .
+ ///
+ OutputDefinition WithOutput(string name, string? description = default);
+
+ ///
+ /// A fluent method for adding an output to .
+ ///
+ OutputDefinition WithOutput(string name, Type type, string? description = default);
+
+ ///
+ /// A fluent method for adding an output to .
+ ///
+ OutputDefinition WithOutput(string name, Type type, Action? setup = default);
+
+ ///
+ /// A fluent method for adding an output to .
+ ///
+ OutputDefinition WithOutput(Action setup);
+
+ ///
+ /// A fluent method for adding an output to .
+ ///
+ OutputDefinition WithOutput(OutputDefinition outputDefinition);
///
/// A fluent method for adding a property to .
diff --git a/src/modules/Elsa.Workflows.Core/Models/ArgumentDefinition.cs b/src/modules/Elsa.Workflows.Core/Models/ArgumentDefinition.cs
index 0239d0400..afd6b5516 100644
--- a/src/modules/Elsa.Workflows.Core/Models/ArgumentDefinition.cs
+++ b/src/modules/Elsa.Workflows.Core/Models/ArgumentDefinition.cs
@@ -18,15 +18,15 @@ public abstract class ArgumentDefinition
///
/// A user friendly name of the input.
///
- public string DisplayName { get; set; } = default!;
+ public string DisplayName { get; set; } = string.Empty;
///
/// A description of the input.
///
- public string Description { get; set; } = default!;
+ public string Description { get; set; } = string.Empty;
///
/// The category to which this input belongs.
///
- public string Category { get; set; } = default!;
+ public string Category { get; set; } = string.Empty;
}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Runtime/Activities/ExecuteWorkflow.cs b/src/modules/Elsa.Workflows.Runtime/Activities/ExecuteWorkflow.cs
new file mode 100644
index 000000000..bc23ea78a
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Runtime/Activities/ExecuteWorkflow.cs
@@ -0,0 +1,90 @@
+using System.Runtime.CompilerServices;
+using Elsa.Common.Models;
+using Elsa.Extensions;
+using Elsa.Workflows.Attributes;
+using Elsa.Workflows.Management;
+using Elsa.Workflows.Models;
+using Elsa.Workflows.Options;
+using Elsa.Workflows.UIHints;
+using JetBrains.Annotations;
+
+namespace Elsa.Workflows.Runtime.Activities;
+
+///
+/// Creates a new workflow instance of the specified workflow and dispatches it for execution.
+///
+[Activity("Elsa", "Composition", "Create a new workflow instance of the specified workflow and execute it.", Kind = ActivityKind.Task)]
+[UsedImplicitly]
+public class ExecuteWorkflow : Activity
+{
+ ///
+ public ExecuteWorkflow([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
+ {
+ }
+
+ ///
+ /// The definition ID of the workflow to execute.
+ ///
+ [Input(
+ DisplayName = "Workflow Definition",
+ Description = "The definition ID of the workflow to execute.",
+ UIHint = InputUIHints.WorkflowDefinitionPicker
+ )]
+ public Input WorkflowDefinitionId { get; set; } = default!;
+
+ ///
+ /// The correlation ID to associate the workflow with.
+ ///
+ [Input(
+ DisplayName = "Correlation ID",
+ Description = "The correlation ID to associate the workflow with."
+ )]
+ public Input CorrelationId { get; set; } = default!;
+
+ ///
+ /// The input to send to the workflow.
+ ///
+ [Input(Description = "The input to send to the workflow.")]
+ public Input?> Input { get; set; } = default!;
+
+ ///
+ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
+ {
+ var result = await ExecuteWorkflowAsync(context);
+ context.SetResult(result);
+ await context.CompleteActivityAsync();
+ }
+
+ private async ValueTask ExecuteWorkflowAsync(ActivityExecutionContext context)
+ {
+ var workflowDefinitionId = WorkflowDefinitionId.Get(context);
+ var input = Input.GetOrDefault(context) ?? new Dictionary();
+ var correlationId = CorrelationId.GetOrDefault(context);
+ var workflowInvoker = context.GetRequiredService();
+ var identityGenerator = context.GetRequiredService();
+ var workflowDefinitionService = context.GetRequiredService();
+ var workflowGraph = await workflowDefinitionService.FindWorkflowGraphAsync(workflowDefinitionId, VersionOptions.Published, context.CancellationToken);
+
+ if (workflowGraph == null)
+ throw new Exception($"No published version of workflow definition with ID {workflowDefinitionId} found.");
+
+ var options = new RunWorkflowOptions
+ {
+ ParentWorkflowInstanceId = context.WorkflowExecutionContext.Id,
+ Input = input,
+ CorrelationId = correlationId,
+ WorkflowInstanceId = identityGenerator.GenerateId()
+ };
+
+ var workflowResult = await workflowInvoker.InvokeAsync(workflowGraph, options, context.CancellationToken);
+ var info = new ExecuteWorkflowResult
+ {
+ WorkflowInstanceId = options.WorkflowInstanceId,
+ Status = workflowResult.WorkflowState.Status,
+ SubStatus = workflowResult.WorkflowState.SubStatus,
+ Output = workflowResult.WorkflowState.Output
+ };
+
+ return info;
+ }
+}
\ No newline at end of file
diff --git a/src/modules/Elsa.Workflows.Runtime/Models/ExecuteWorkflowResult.cs b/src/modules/Elsa.Workflows.Runtime/Models/ExecuteWorkflowResult.cs
new file mode 100644
index 000000000..b2bcd36e7
--- /dev/null
+++ b/src/modules/Elsa.Workflows.Runtime/Models/ExecuteWorkflowResult.cs
@@ -0,0 +1,14 @@
+namespace Elsa.Workflows.Runtime;
+
+///
+/// Represents the result of executing a workflow.
+///
+public class ExecuteWorkflowResult
+{
+ public string WorkflowDefinitionVersionId { get; set; } = default!;
+ public string WorkflowInstanceId { get; set; } = default!;
+ public string? CorrelationId { get; set; }
+ public WorkflowStatus Status { get; set; }
+ public WorkflowSubStatus SubStatus { get; set; }
+ public IDictionary? Output { get; set; }
+}
\ No newline at end of file
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs
index e69423a11..b0db161d7 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Abstractions/AppComponentTest.cs
@@ -1,6 +1,7 @@
+using Elsa.Workflows.ComponentTests.Fixtures;
using Microsoft.Extensions.DependencyInjection;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Abstractions;
[Collection(nameof(AppCollection))]
public abstract class AppComponentTest(App app) : IDisposable
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Consumers/WorkflowDefinitionEventConsumer.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Consumers/WorkflowDefinitionEventConsumer.cs
index 0418129a4..9a637faff 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Consumers/WorkflowDefinitionEventConsumer.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Consumers/WorkflowDefinitionEventConsumer.cs
@@ -4,7 +4,7 @@ using Elsa.Testing.Shared.Services;
using Hangfire.Annotations;
using MassTransit;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Consumers;
[UsedImplicitly]
public class WorkflowDefinitionEventConsumer(WorkflowDefinitionEvents workflowDefinitionEvents) : IConsumer
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Decorators/EventPublishingChangeTokenSignaler.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Decorators/EventPublishingChangeTokenSignaler.cs
index 835331052..daac22ba1 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Decorators/EventPublishingChangeTokenSignaler.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Decorators/EventPublishingChangeTokenSignaler.cs
@@ -4,7 +4,7 @@ using Elsa.Testing.Shared.Services;
using Hangfire.Annotations;
using Microsoft.Extensions.Primitives;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Decorators;
///
/// Provides a decorator for the `IChangeTokenSignaler` interface that triggers change token events.
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs
index 094a8e784..bcf1d377a 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/App.cs
@@ -1,6 +1,6 @@
using Hangfire.Annotations;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Fixtures;
[UsedImplicitly]
public class App : IAsyncLifetime
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/AppCollection.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/AppCollection.cs
index f83071692..81f27ed3f 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/AppCollection.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/AppCollection.cs
@@ -1,4 +1,4 @@
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Fixtures;
[CollectionDefinition(nameof(AppCollection))]
public class AppCollection : ICollectionFixture
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Cluster.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Cluster.cs
index e07388593..6ef20f1a5 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Cluster.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Cluster.cs
@@ -1,6 +1,6 @@
using Hangfire.Annotations;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Fixtures;
[UsedImplicitly]
public class Cluster(Infrastructure infrastructure) : IAsyncDisposable
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Infrastructure.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Infrastructure.cs
index 5ce02bc31..81f2682e9 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Infrastructure.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/Infrastructure.cs
@@ -1,7 +1,7 @@
using Testcontainers.PostgreSql;
using Testcontainers.RabbitMq;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Fixtures;
public class Infrastructure : IAsyncLifetime
{
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs
index cec02baaf..f589d8237 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Fixtures/WorkflowServer.cs
@@ -3,7 +3,6 @@ using System.Reflection;
using Elsa.Agents;
using Elsa.Alterations.Extensions;
using Elsa.Caching;
-using Elsa.EntityFrameworkCore;
using Elsa.EntityFrameworkCore.Extensions;
using Elsa.EntityFrameworkCore.Modules.Alterations;
using Elsa.EntityFrameworkCore.Modules.Identity;
@@ -14,6 +13,10 @@ using Elsa.Identity.Providers;
using Elsa.MassTransit.Extensions;
using Elsa.Testing.Shared.Handlers;
using Elsa.Testing.Shared.Services;
+using Elsa.Workflows.ComponentTests.Consumers;
+using Elsa.Workflows.ComponentTests.Decorators;
+using Elsa.Workflows.ComponentTests.Materializers;
+using Elsa.Workflows.ComponentTests.WorkflowProviders;
using Elsa.Workflows.Management;
using Elsa.Workflows.Runtime.Distributed.Extensions;
using FluentStorage;
@@ -25,7 +28,7 @@ using Microsoft.Extensions.DependencyInjection;
using Refit;
using static Elsa.Api.Client.RefitSettingsHelper;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Fixtures;
[UsedImplicitly]
public class WorkflowServer(Infrastructure infrastructure, string url) : WebApplicationFactory
@@ -73,7 +76,7 @@ public class WorkflowServer(Infrastructure infrastructure, string url) : WebAppl
});
elsa.UseMassTransit(massTransit =>
{
- massTransit.UseRabbitMq(rabbitMqConnectionString);
+ //massTransit.UseRabbitMq(rabbitMqConnectionString);
massTransit.AddConsumer("elsa-test-workflow-definition-updates", true);
});
elsa.UseIdentity(identity => identity.UseEntityFrameworkCore(ef => ef.UsePostgreSql(dbConnectionString)));
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/Materializers/TestWorkflowMaterializer.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/Materializers/TestWorkflowMaterializer.cs
index ea1f04758..c3756cd0f 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/Materializers/TestWorkflowMaterializer.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/Materializers/TestWorkflowMaterializer.cs
@@ -1,9 +1,10 @@
using Elsa.Workflows.Activities;
+using Elsa.Workflows.ComponentTests.WorkflowProviders;
using Elsa.Workflows.Management;
using Elsa.Workflows.Management.Entities;
using Elsa.Workflows.Runtime;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.Materializers;
///
/// A workflow materializer that deserializes workflows created from .
diff --git a/test/component/Elsa.Workflows.ComponentTests/Helpers/WorkflowProviders/TestWorkflowProvider.cs b/test/component/Elsa.Workflows.ComponentTests/Helpers/WorkflowProviders/TestWorkflowProvider.cs
index 147f163d7..b7ecadb32 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Helpers/WorkflowProviders/TestWorkflowProvider.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Helpers/WorkflowProviders/TestWorkflowProvider.cs
@@ -1,6 +1,6 @@
using Elsa.Workflows.Runtime;
-namespace Elsa.Workflows.ComponentTests.Helpers;
+namespace Elsa.Workflows.ComponentTests.WorkflowProviders;
public class TestWorkflowProvider : IWorkflowsProvider
{
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/FlowJoins/Tests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/FlowJoins/Tests.cs
index 3e207352a..605e2da56 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/FlowJoins/Tests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Activities/FlowJoins/Tests.cs
@@ -1,4 +1,5 @@
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Workflows.ComponentTests.Scenarios.Activities.FlowJoins;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/BasicWorkflows/HelloWorldTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/BasicWorkflows/HelloWorldTests.cs
index 4ad364963..7d02e82f2 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/BasicWorkflows/HelloWorldTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/BasicWorkflows/HelloWorldTests.cs
@@ -2,7 +2,8 @@
using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
using Elsa.Testing.Shared.Extensions;
using Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Execute;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
namespace Elsa.Workflows.ComponentTests.Scenarios.BasicWorkflows;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/BulkDispatchWorkflows/BulkDispatchWorkflowsTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/BulkDispatchWorkflows/BulkDispatchWorkflowsTests.cs
index 9696a0543..e279acaf2 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/BulkDispatchWorkflows/BulkDispatchWorkflowsTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/BulkDispatchWorkflows/BulkDispatchWorkflowsTests.cs
@@ -1,7 +1,8 @@
using Elsa.Common.Models;
using Elsa.Testing.Shared;
using Elsa.Testing.Shared.Services;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.ComponentTests.Scenarios.BulkDispatchWorkflows.Workflows;
using Elsa.Workflows.Models;
using Elsa.Workflows.Runtime;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/CachingAndWorkflowDefinitionActivity/WorkflowDefinitionActivityTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/CachingAndWorkflowDefinitionActivity/WorkflowDefinitionActivityTests.cs
index fdc54ee61..e25763ef5 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/CachingAndWorkflowDefinitionActivity/WorkflowDefinitionActivityTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/CachingAndWorkflowDefinitionActivity/WorkflowDefinitionActivityTests.cs
@@ -1,4 +1,5 @@
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.Management;
using Elsa.Workflows.Management.Filters;
using Microsoft.Extensions.DependencyInjection;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/ClusteredHosting/ActivityRegistrySyncTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/ClusteredHosting/ActivityRegistrySyncTests.cs
index 005e85fce..b19d54767 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/ClusteredHosting/ActivityRegistrySyncTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/ClusteredHosting/ActivityRegistrySyncTests.cs
@@ -1,4 +1,5 @@
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.Management;
using Elsa.Workflows.Management.Models;
using Elsa.Workflows.Models;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/DispatchWorkflows/DispatchWorkflowsTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/DispatchWorkflows/DispatchWorkflowsTests.cs
index 050b1a1c5..1b3de1d37 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/DispatchWorkflows/DispatchWorkflowsTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/DispatchWorkflows/DispatchWorkflowsTests.cs
@@ -1,7 +1,8 @@
using Elsa.Common.Models;
using Elsa.Testing.Shared;
using Elsa.Testing.Shared.Services;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.ComponentTests.Scenarios.DispatchWorkflows.Workflows;
using Elsa.Workflows.Models;
using Elsa.Workflows.Runtime;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/ExecuteWorkflowsTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/ExecuteWorkflowsTests.cs
new file mode 100644
index 000000000..c47025d46
--- /dev/null
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/ExecuteWorkflowsTests.cs
@@ -0,0 +1,31 @@
+using Elsa.Common.Models;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
+using Elsa.Workflows.ComponentTests.Scenarios.ExecuteWorkflows.Workflows;
+using Elsa.Workflows.Models;
+using Elsa.Workflows.Runtime;
+using Elsa.Workflows.Runtime.Messages;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Elsa.Workflows.ComponentTests.Scenarios.ExecuteWorkflows;
+
+public class ExecuteWorkflowsTests : AppComponentTest
+{
+ private readonly IWorkflowRuntime _workflowRuntime;
+
+ public ExecuteWorkflowsTests(App app) : base(app)
+ {
+ _workflowRuntime = Scope.ServiceProvider.GetRequiredService();
+ }
+
+ [Fact]
+ public async Task ExecuteWorkflow_ShouldExecuteWorkflow()
+ {
+ var workflowClient = await _workflowRuntime.CreateClientAsync();
+ await workflowClient.CreateInstanceAsync(new CreateWorkflowInstanceRequest
+ {
+ WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionId(MainWorkflow.DefinitionId, VersionOptions.Published)
+ });
+ await workflowClient.RunInstanceAsync(RunWorkflowInstanceRequest.Empty);
+ }
+}
\ No newline at end of file
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/Workflows/MainWorkflow.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/Workflows/MainWorkflow.cs
new file mode 100644
index 000000000..754fb81df
--- /dev/null
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/Workflows/MainWorkflow.cs
@@ -0,0 +1,33 @@
+using System.Text.Json;
+using Elsa.Workflows.Activities;
+using Elsa.Workflows.Runtime;
+using Elsa.Workflows.Runtime.Activities;
+
+namespace Elsa.Workflows.ComponentTests.Scenarios.ExecuteWorkflows.Workflows;
+
+public class MainWorkflow : WorkflowBase
+{
+ public static readonly string DefinitionId = Guid.NewGuid().ToString();
+
+ protected override void Build(IWorkflowBuilder builder)
+ {
+ builder.WithDefinitionId(DefinitionId);
+ var workflowResult = builder.WithVariable();
+ builder.Root = new Sequence
+ {
+ Activities =
+ {
+ new ExecuteWorkflow
+ {
+ WorkflowDefinitionId = new(SubroutineWorkflow.DefinitionId),
+ Input = new(new Dictionary
+ {
+ ["Value"] = 21
+ }),
+ Result = new(workflowResult)
+ },
+ new WriteLine(context => $"Subroutine output: {JsonSerializer.Serialize(workflowResult.Get(context))}")
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/Workflows/SubroutineWorkflow.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/Workflows/SubroutineWorkflow.cs
new file mode 100644
index 000000000..531c6cfda
--- /dev/null
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/ExecuteWorkflows/Workflows/SubroutineWorkflow.cs
@@ -0,0 +1,31 @@
+using Elsa.Extensions;
+using Elsa.Workflows.Activities;
+using Elsa.Workflows.Management.Activities.SetOutput;
+using Hangfire.Annotations;
+
+namespace Elsa.Workflows.ComponentTests.Scenarios.ExecuteWorkflows.Workflows;
+
+[UsedImplicitly]
+public class SubroutineWorkflow : WorkflowBase
+{
+ public static readonly string DefinitionId = Guid.NewGuid().ToString();
+ protected override void Build(IWorkflowBuilder builder)
+ {
+ builder.WithDefinitionId(DefinitionId);
+ var valueInput = builder.WithInput("Value");
+ var output = builder.WithOutput("Output");
+
+ builder.Root = new Sequence
+ {
+ Activities =
+ {
+ new WriteLine(context => $"Running subroutine on value {context.GetInput(valueInput)}..."),
+ new SetOutput
+ {
+ OutputName = new(output.Name),
+ OutputValue = new(context => context.GetInput(valueInput) * 2)
+ }
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows/HttpHelloWorldTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows/HttpHelloWorldTests.cs
index 930f2b31e..dc27db6f3 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows/HttpHelloWorldTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows/HttpHelloWorldTests.cs
@@ -1,4 +1,5 @@
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
namespace Elsa.Workflows.ComponentTests.Scenarios.HttpWorkflows;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows/ResumeSpecificHttpWorkflowInstanceTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows/ResumeSpecificHttpWorkflowInstanceTests.cs
index 77d696f0e..30d46e43c 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows/ResumeSpecificHttpWorkflowInstanceTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/HttpWorkflows/ResumeSpecificHttpWorkflowInstanceTests.cs
@@ -1,5 +1,6 @@
using System.Net;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Workflows.ComponentTests.Scenarios.HttpWorkflows;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/LogPersistenceModes/InputOutputLoggingTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/LogPersistenceModes/InputOutputLoggingTests.cs
index 68d1171e5..4d2a5629e 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/LogPersistenceModes/InputOutputLoggingTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/LogPersistenceModes/InputOutputLoggingTests.cs
@@ -4,7 +4,8 @@ using Elsa.Api.Client.Resources.WorkflowInstances.Models;
using Elsa.Common.Entities;
using Elsa.Testing.Shared.Extensions;
using Elsa.Workflows.Activities;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.Helpers;
using Elsa.Workflows.Runtime;
using Elsa.Workflows.Runtime.Entities;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Multitenancy/MultitenancyTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Multitenancy/MultitenancyTests.cs
index a8f6c05b6..06b5d600c 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Multitenancy/MultitenancyTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Multitenancy/MultitenancyTests.cs
@@ -1,5 +1,6 @@
using Elsa.Common.Models;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.Management;
using Elsa.Workflows.Management.Filters;
using Microsoft.Extensions.DependencyInjection;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Variables/CountdownWorkflowTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Variables/CountdownWorkflowTests.cs
index 428c28a7b..a09a46863 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/Variables/CountdownWorkflowTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/Variables/CountdownWorkflowTests.cs
@@ -1,6 +1,7 @@
using Elsa.Expressions.Helpers;
using Elsa.Extensions;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.ComponentTests.Scenarios.Variables.Workflows;
using Elsa.Workflows.Management;
using Elsa.Workflows.Models;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/AutoUpdateTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/AutoUpdateTests.cs
index 8d25b686a..fdd30c25e 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/AutoUpdateTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/AutoUpdateTests.cs
@@ -1,7 +1,8 @@
using Elsa.Http;
using Elsa.Testing.Shared;
using Elsa.Testing.Shared.Services;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.Management;
using Elsa.Workflows.Management.Filters;
using Elsa.Workflows.Runtime.Filters;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/DeleteWorkflowTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/DeleteWorkflowTests.cs
index 2068a3812..96fb810be 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/DeleteWorkflowTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/DeleteWorkflowTests.cs
@@ -1,6 +1,7 @@
using Elsa.Testing.Shared;
using Elsa.Testing.Shared.Services;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.ComponentTests.Scenarios.WorkflowActivities.Workflows;
using Elsa.Workflows.Management;
using Microsoft.Extensions.DependencyInjection;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/SaveWorkflowTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/SaveWorkflowTests.cs
index e6e09fc88..ff84ede43 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/SaveWorkflowTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowActivities/SaveWorkflowTests.cs
@@ -1,4 +1,5 @@
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.Management;
using Elsa.Workflows.Management.Activities.WorkflowDefinitionActivity;
using Elsa.Workflows.Management.Models;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowCompletion/WorkflowCompletionTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowCompletion/WorkflowCompletionTests.cs
index 7dc704d0c..08a4d7710 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowCompletion/WorkflowCompletionTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowCompletion/WorkflowCompletionTests.cs
@@ -2,7 +2,8 @@
using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
using Elsa.Testing.Shared.Extensions;
using Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Execute;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
namespace Elsa.Workflows.ComponentTests.Scenarios.WorkflowCompletion;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionRefresh/DynamicEndpointTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionRefresh/DynamicEndpointTests.cs
index a21b5ab36..32484c686 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionRefresh/DynamicEndpointTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionRefresh/DynamicEndpointTests.cs
@@ -1,6 +1,7 @@
using System.Net;
using Elsa.Testing.Shared.Services;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
using Elsa.Workflows.Runtime;
using Microsoft.Extensions.DependencyInjection;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionReload/ReloadWorkflowTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionReload/ReloadWorkflowTests.cs
index 3fb61269b..3f96d9dbb 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionReload/ReloadWorkflowTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowDefinitionReload/ReloadWorkflowTests.cs
@@ -1,7 +1,10 @@
using System.Net;
using Elsa.Common.Models;
using Elsa.Workflows.Activities;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
+using Elsa.Workflows.ComponentTests.Materializers;
+using Elsa.Workflows.ComponentTests.WorkflowProviders;
using Elsa.Workflows.Management;
using Elsa.Workflows.Runtime;
using Humanizer;
diff --git a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowJsonStructures/WorkflowJsonStructureTests.cs b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowJsonStructures/WorkflowJsonStructureTests.cs
index bd8514f77..f1ac96583 100644
--- a/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowJsonStructures/WorkflowJsonStructureTests.cs
+++ b/test/component/Elsa.Workflows.ComponentTests/Scenarios/WorkflowJsonStructures/WorkflowJsonStructureTests.cs
@@ -1,5 +1,6 @@
using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
-using Elsa.Workflows.ComponentTests.Helpers;
+using Elsa.Workflows.ComponentTests.Abstractions;
+using Elsa.Workflows.ComponentTests.Fixtures;
namespace Elsa.Workflows.ComponentTests.Scenarios.WorkflowJsonStructures;