@camunda/e2e-test-suite 0.0.1228 → 0.0.1230

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,19 +2,19 @@ import { Page, Locator } from '@playwright/test';
2
2
  export declare class OCIdentityClusterVariablesPage {
3
3
  private page;
4
4
  readonly variablesList: Locator;
5
- readonly editVariableButton: (variableName: string) => Locator;
5
+ readonly editVariableButton: (variableName: string, scope?: string) => Locator;
6
6
  readonly editVariableModal: Locator;
7
7
  readonly variableValueField: Locator;
8
8
  readonly saveVariableButton: Locator;
9
9
  readonly closeEditVariableModal: Locator;
10
10
  readonly cancelButton: Locator;
11
- readonly variableRow: (variableName: string) => Locator;
11
+ readonly variableRow: (variableName: string, scope?: string) => Locator;
12
12
  readonly monacoEditor: Locator;
13
13
  readonly monacoEditorTextArea: Locator;
14
14
  readonly successMessage: Locator;
15
15
  readonly editMenuItem: Locator;
16
16
  constructor(page: Page);
17
- editVariable(variableName: string, newValue: string): Promise<void>;
18
- assertVariableExists(variableName: string): Promise<void>;
19
- assertVariableValue(variableName: string, expectedValue: string): Promise<void>;
17
+ editVariable(variableName: string, newValue: string, scope?: string): Promise<void>;
18
+ assertVariableExists(variableName: string, scope?: string): Promise<void>;
19
+ assertVariableValue(variableName: string, expectedValue: string, scope?: string): Promise<void>;
20
20
  }
@@ -20,11 +20,20 @@ class OCIdentityClusterVariablesPage {
20
20
  constructor(page) {
21
21
  this.page = page;
22
22
  this.variablesList = page.locator('table.cds--data-table');
23
- this.variableRow = (variableName) => this.variablesList
24
- .locator('tbody')
25
- .getByRole('row')
26
- .filter({ hasText: variableName });
27
- this.editVariableButton = (variableName) => this.variableRow(variableName).getByRole('button', { name: 'Options' });
23
+ this.variableRow = (variableName, scope) => {
24
+ const rows = this.variablesList
25
+ .locator('tbody')
26
+ .getByRole('row')
27
+ .filter({ hasText: variableName });
28
+ const scopeLabel = scope ? `Tenant: ${scope}` : 'Global';
29
+ return rows
30
+ .getByRole('cell', { name: scopeLabel, exact: true })
31
+ .first()
32
+ .locator('..');
33
+ };
34
+ this.editVariableButton = (variableName, scope) => this.variableRow(variableName, scope).getByRole('button', {
35
+ name: 'Options',
36
+ });
28
37
  this.editVariableModal = page.getByRole('dialog', {
29
38
  name: /Edit.*variable/i,
30
39
  });
@@ -45,8 +54,8 @@ class OCIdentityClusterVariablesPage {
45
54
  .locator('button[role="menuitem"]')
46
55
  .filter({ hasText: /^Edit$/ });
47
56
  }
48
- async editVariable(variableName, newValue) {
49
- await this.editVariableButton(variableName).click();
57
+ async editVariable(variableName, newValue, scope) {
58
+ await this.editVariableButton(variableName, scope).click();
50
59
  await (0, test_1.expect)(this.editMenuItem).toBeVisible();
51
60
  await this.editMenuItem.click();
52
61
  await (0, test_1.expect)(this.variableValueField).toBeVisible();
@@ -63,21 +72,21 @@ class OCIdentityClusterVariablesPage {
63
72
  await (0, test_1.expect)(this.successMessage).toBeVisible();
64
73
  await (0, test_1.expect)(this.editVariableModal).toBeHidden();
65
74
  }
66
- async assertVariableExists(variableName) {
75
+ async assertVariableExists(variableName, scope) {
67
76
  // Cluster variables are created via the API and indexed asynchronously in
68
77
  // the search server, so a freshly-created variable may not yet appear in
69
78
  // the search-backed Admin UI list when the tab first renders. The list is
70
79
  // not auto-refreshed, so a single visibility check against the default 5s
71
80
  // timeout can miss it. Reload between attempts to re-fetch the list until
72
81
  // the row appears.
73
- await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.variableRow(variableName), {
82
+ await (0, expectLocatorWithRetry_1.expectLocatorWithRetry)(this.page, this.variableRow(variableName, scope), {
74
83
  postAction: async () => {
75
84
  await this.page.reload();
76
85
  },
77
86
  });
78
87
  }
79
- async assertVariableValue(variableName, expectedValue) {
80
- const row = this.variableRow(variableName);
88
+ async assertVariableValue(variableName, expectedValue, scope) {
89
+ const row = this.variableRow(variableName, scope);
81
90
  await (0, test_1.expect)(row).toContainText(expectedValue);
82
91
  }
83
92
  }
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OCIdentityRolesPage = void 0;
4
4
  const test_1 = require("@playwright/test");
5
5
  const UtilitiesPage_1 = require("../SM-8.9/UtilitiesPage");
6
+ const expectLocatorWithPagination_1 = require("../../utils/assertionHelpers/expectLocatorWithPagination");
7
+ const findLocatorWithPagination_1 = require("../../utils/assertionHelpers/findLocatorWithPagination");
6
8
  class OCIdentityRolesPage {
7
9
  page;
8
10
  selectResourceTypeTab;
@@ -100,6 +102,12 @@ class OCIdentityRolesPage {
100
102
  await this.selectResourceTypeTab('Mapping Rules').click();
101
103
  }
102
104
  async clickRole(roleID) {
105
+ // The roles table paginates at 10 rows and the cluster already ships six
106
+ // built-in roles, so a role this suite created is regularly on page 2 and
107
+ // is never in the DOM on page 1 - walk the pages before asserting.
108
+ await (0, findLocatorWithPagination_1.findLocatorWithPagination)(this.page, this.roleCell(roleID).first(), {
109
+ timeout: 60000,
110
+ });
103
111
  await (0, test_1.expect)(this.roleCell(roleID).first()).toBeVisible({ timeout: 60000 });
104
112
  await this.roleCell(roleID).first().click();
105
113
  }
@@ -122,15 +130,26 @@ class OCIdentityRolesPage {
122
130
  await this.createNameField.fill(role.name);
123
131
  await this.createRoleModalCreateButton.click();
124
132
  await (0, test_1.expect)(this.createRoleModal).not.toBeVisible();
125
- await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(this.page, this.rolesList
133
+ // A freshly created role sorts to the end of a table that paginates at 10
134
+ // rows, so on a cluster that already holds ten roles it lands on page 2.
135
+ // Polling page 1 can never see it - page through instead.
136
+ await (0, expectLocatorWithPagination_1.expectLocatorWithPagination)(this.page, this.rolesList
126
137
  .getByRole('cell', {
127
138
  name: role.name,
128
139
  })
129
- .first(), role.id, 10000, false, 10);
140
+ .first(), { maxRetries: 10 });
130
141
  }
131
142
  async deleteRole(name, options) {
132
143
  const { throwError = true } = options || {};
133
144
  try {
145
+ // Same pagination trap as createRole: the row - and therefore its
146
+ // Delete button - is regularly on page 2 by the time cleanup runs. With
147
+ // throwError:false the miss is swallowed, which is how stale roles pile
148
+ // up on the cluster and push later roles off page 1 in the first place.
149
+ const found = await (0, findLocatorWithPagination_1.findLocatorWithPagination)(this.page, this.deleteRoleButton(name), { timeout: 30000 });
150
+ if (!found) {
151
+ throw new Error(`Role "${name}" was not found on any page of the roles table`);
152
+ }
134
153
  await this.deleteRoleButton(name).click();
135
154
  await (0, test_1.expect)(this.deleteRoleModal).toBeVisible();
136
155
  await this.deleteRoleModalDeleteButton.click();
@@ -12,7 +12,7 @@ declare class TaskPanelPage {
12
12
  readonly licenseKeyTagNonProduction: Locator;
13
13
  readonly licenseKeyTagProduction: Locator;
14
14
  constructor(page: Page);
15
- openTask(name: string, assignButton?: boolean): Promise<void>;
15
+ openTask(name: string, assignButton?: boolean, fallbackName?: string): Promise<void>;
16
16
  filterBy(option: 'All open' | 'Unassigned' | 'Assigned to me' | 'Completed'): Promise<void>;
17
17
  scrollToLastTask(name: string): Promise<void>;
18
18
  scrollToFirstTask(name: string): Promise<void>;
@@ -36,31 +36,41 @@ class TaskPanelPage {
36
36
  exact: true,
37
37
  });
38
38
  }
39
- async openTask(name, assignButton = true) {
39
+ async openTask(name, assignButton = true, fallbackName) {
40
40
  const maxAttempts = 10;
41
+ const taskNames = [name, fallbackName].filter((taskName) => Boolean(taskName));
41
42
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
43
+ let lastError;
42
44
  try {
43
45
  await this.page.waitForLoadState('domcontentloaded');
44
- await this.availableTasks
45
- .getByText(name, { exact: true })
46
- .nth(0)
47
- .click({ timeout: constants_1._1_SECOND_IN_MS * 4 });
48
- if (assignButton) {
49
- await (0, test_1.expect)(this.assignToMeButton).toBeVisible({
50
- timeout: constants_1._1_SECOND_IN_MS * 10,
51
- });
46
+ for (const taskName of taskNames) {
47
+ try {
48
+ await this.availableTasks
49
+ .getByText(taskName, { exact: true })
50
+ .first()
51
+ .click({ timeout: constants_1._1_SECOND_IN_MS * 4 });
52
+ if (assignButton) {
53
+ await (0, test_1.expect)(this.assignToMeButton).toBeVisible({
54
+ timeout: constants_1._1_SECOND_IN_MS * 10,
55
+ });
56
+ }
57
+ return;
58
+ }
59
+ catch (error) {
60
+ lastError = error;
61
+ }
52
62
  }
53
- return;
54
63
  }
55
64
  catch (error) {
56
- if (attempt < maxAttempts) {
57
- console.warn(`Attempt ${attempt} failed. Reloading page...`);
58
- await this.page.reload();
59
- await this.page.waitForLoadState('domcontentloaded');
60
- }
61
- else {
62
- throw new Error(`Failed to open task "${name}" after ${maxAttempts} attempts: ${error}`);
63
- }
65
+ lastError = error;
66
+ }
67
+ if (attempt < maxAttempts) {
68
+ console.warn(`Attempt ${attempt} failed. Reloading page...`);
69
+ await this.page.reload();
70
+ await this.page.waitForLoadState('domcontentloaded');
71
+ }
72
+ else {
73
+ throw new Error(`Failed to open task "${name}" after ${maxAttempts} attempts: ${lastError}`);
64
74
  }
65
75
  }
66
76
  }
@@ -24,7 +24,7 @@ export declare function modelRestConnector(modelerCreatePage: ModelerCreatePage,
24
24
  username: string;
25
25
  password: string;
26
26
  }): Promise<void>;
27
- export declare function assertLocatorVisibleWithPaginated(page: Page, locator: Locator, text: string): Promise<void>;
27
+ export declare function assertLocatorVisibleWithPaginated(page: Page, locator: Locator, text: string, timeout?: number): Promise<void>;
28
28
  export declare function assertLocatorVisibleWithRetry(page: Page, locator: Locator, text: string, timeout?: number, notVisible?: boolean, maxRetries?: number, clickLocator?: Locator): Promise<void>;
29
29
  export declare function assertPageTextWithRetry(page: Page, text: string, notVisible?: boolean, timeout?: number, maxRetries?: number): Promise<void>;
30
30
  export declare function modelAndRunConnectorsTimerEventDiagram(modelerCreatePage: ModelerCreatePage, modelerHomePage: ModelerHomePage, processName: string, page: Page, connectorMarketplacePage: ConnectorMarketplacePage, connectorTemplatePage: ConnectorTemplatePage, tenant?: string): Promise<void>;
@@ -48,10 +48,13 @@ async function assignMappingToRole(page, ocIdentityHomePage, ocIdentityRolesPage
48
48
  });
49
49
  }
50
50
  catch (error) {
51
- await ocIdentityRolesPage.createRole({ id: role, name: role });
51
+ // Register the id before creating so a create that fails part-way still
52
+ // leaves the role on the afterEach cleanup list; a leaked role stays on
53
+ // the cluster forever and pushes later roles onto page 2 of the table.
52
54
  if (testMappings && role.toLowerCase() != 'admin') {
53
55
  testMappings.roleIds.push(role);
54
56
  }
57
+ await ocIdentityRolesPage.createRole({ id: role, name: role });
55
58
  }
56
59
  await ocIdentityRolesPage.assignMappingRuleToRole(role, mappingRuleId);
57
60
  await assertLocatorVisibleWithPaginated(page, ocIdentityRolesPage.mappingRuleRow(mappingRuleId).first(), `${mappingRuleId} Mapping Rule`);
@@ -231,7 +234,7 @@ async function modelRestConnector(modelerCreatePage, connectorSettingsPage, conn
231
234
  await (0, sleep_1.sleep)(10000);
232
235
  }
233
236
  exports.modelRestConnector = modelRestConnector;
234
- async function assertLocatorVisibleWithPaginated(page, locator, text) {
237
+ async function assertLocatorVisibleWithPaginated(page, locator, text, timeout = 20000) {
235
238
  const maxRetries = 6;
236
239
  for (let attempt = 0; attempt < maxRetries; attempt++) {
237
240
  try {
@@ -240,7 +243,10 @@ async function assertLocatorVisibleWithPaginated(page, locator, text) {
240
243
  if (attempt > 2) {
241
244
  await (0, findLocatorInPaginatedList_1.findLocatorInPaginatedList)(page, locator);
242
245
  }
243
- await (0, test_1.expect)(locator).toBeVisible();
246
+ // Without an explicit budget this inherits the 5s expect default, so
247
+ // six attempts only poll for ~60s in total - not enough for a freshly
248
+ // assigned mapping rule to show up on the role detail page.
249
+ await (0, test_1.expect)(locator).toBeVisible({ timeout });
244
250
  return;
245
251
  }
246
252
  catch (error) {
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler" exporterVersion="52c6ff6" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.9.0">
3
+ <bpmn:process id="cluster_variable_tenant_updatable_json" name="Tenant Cluster Variable Updatable JSON" isExecutable="true">
4
+ <bpmn:startEvent id="StartEvent_1">
5
+ <bpmn:extensionElements>
6
+ <zeebe:ioMapping>
7
+ <zeebe:output source="=camunda.vars.tenant.UPDATABLE_API_INFO.endpoint" target="URL" />
8
+ <zeebe:output source="=camunda.vars.tenant.UPDATABLE_API_INFO.timeout_ms" target="TIMEOUT_MS" />
9
+ <zeebe:output source="=camunda.vars.tenant.UPDATABLE_API_INFO.array" target="ARRAY" />
10
+ </zeebe:ioMapping>
11
+ </bpmn:extensionElements>
12
+ <bpmn:outgoing>Flow_1k9dndp</bpmn:outgoing>
13
+ </bpmn:startEvent>
14
+ <bpmn:sequenceFlow id="Flow_1k9dndp" sourceRef="StartEvent_1" targetRef="Event_1mc2ikr" />
15
+ <bpmn:endEvent id="Event_1mc2ikr">
16
+ <bpmn:incoming>Flow_1k9dndp</bpmn:incoming>
17
+ </bpmn:endEvent>
18
+ </bpmn:process>
19
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
20
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="cluster_variable_tenant_updatable_json">
21
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
22
+ <dc:Bounds x="179" y="159" width="36" height="36" />
23
+ </bpmndi:BPMNShape>
24
+ <bpmndi:BPMNShape id="Event_1mc2ikr_di" bpmnElement="Event_1mc2ikr">
25
+ <dc:Bounds x="312" y="159" width="36" height="36" />
26
+ </bpmndi:BPMNShape>
27
+ <bpmndi:BPMNEdge id="Flow_1k9dndp_di" bpmnElement="Flow_1k9dndp">
28
+ <di:waypoint x="215" y="177" />
29
+ <di:waypoint x="312" y="177" />
30
+ </bpmndi:BPMNEdge>
31
+ </bpmndi:BPMNPlane>
32
+ </bpmndi:BPMNDiagram>
33
+ </bpmn:definitions>
@@ -0,0 +1,59 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
3
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
4
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
5
+ xmlns:zeebe="http://camunda.org/schema/zeebe/1.0"
6
+ xmlns:modeler="http://camunda.org/schema/modeler/1.0"
7
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1"
8
+ targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler"
9
+ exporterVersion="52c6ff6" modeler:executionPlatform="Camunda Cloud"
10
+ modeler:executionPlatformVersion="8.9.0">
11
+ <bpmn:process id="cluster_variable_tenant_original_json" name="Tenant Cluster Variable Original JSON"
12
+ isExecutable="true">
13
+ <bpmn:startEvent id="StartEvent_1">
14
+ <bpmn:extensionElements>
15
+ <zeebe:ioMapping>
16
+ <zeebe:output source="=camunda.vars.tenant.ORIGINAL_API_INFO.endpoint" target="URL" />
17
+ <zeebe:output source="=camunda.vars.tenant.ORIGINAL_API_INFO.timeout_ms" target="TIMEOUT_MS" />
18
+ <zeebe:output source="=camunda.vars.tenant.ORIGINAL_API_INFO.array" target="ARRAY" />
19
+ </zeebe:ioMapping>
20
+ </bpmn:extensionElements>
21
+ <bpmn:outgoing>Flow_1k9dndp</bpmn:outgoing>
22
+ </bpmn:startEvent>
23
+ <bpmn:sequenceFlow id="Flow_1k9dndp" sourceRef="StartEvent_1" targetRef="Activity_1whhatc" />
24
+ <bpmn:endEvent id="Event_1mc2ikr">
25
+ <bpmn:incoming>Flow_0wixfng</bpmn:incoming>
26
+ </bpmn:endEvent>
27
+ <bpmn:sequenceFlow id="Flow_0wixfng" sourceRef="Activity_1whhatc" targetRef="Event_1mc2ikr" />
28
+ <bpmn:userTask id="Activity_1whhatc" name="Preview JSON tenant cluster variables">
29
+ <bpmn:extensionElements>
30
+ <zeebe:userTask />
31
+ <zeebe:formDefinition formId="Form_ClusterVarJSON" />
32
+ </bpmn:extensionElements>
33
+ <bpmn:incoming>Flow_1k9dndp</bpmn:incoming>
34
+ <bpmn:outgoing>Flow_0wixfng</bpmn:outgoing>
35
+ </bpmn:userTask>
36
+ </bpmn:process>
37
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
38
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="cluster_variable_tenant_original_json">
39
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
40
+ <dc:Bounds x="342" y="272" width="36" height="36" />
41
+ </bpmndi:BPMNShape>
42
+ <bpmndi:BPMNShape id="Event_1mc2ikr_di" bpmnElement="Event_1mc2ikr">
43
+ <dc:Bounds x="582" y="272" width="36" height="36" />
44
+ </bpmndi:BPMNShape>
45
+ <bpmndi:BPMNShape id="Activity_0lwojkk_di" bpmnElement="Activity_1whhatc">
46
+ <dc:Bounds x="430" y="250" width="100" height="80" />
47
+ <bpmndi:BPMNLabel />
48
+ </bpmndi:BPMNShape>
49
+ <bpmndi:BPMNEdge id="Flow_1k9dndp_di" bpmnElement="Flow_1k9dndp">
50
+ <di:waypoint x="378" y="290" />
51
+ <di:waypoint x="430" y="290" />
52
+ </bpmndi:BPMNEdge>
53
+ <bpmndi:BPMNEdge id="Flow_0wixfng_di" bpmnElement="Flow_0wixfng">
54
+ <di:waypoint x="530" y="290" />
55
+ <di:waypoint x="582" y="290" />
56
+ </bpmndi:BPMNEdge>
57
+ </bpmndi:BPMNPlane>
58
+ </bpmndi:BPMNDiagram>
59
+ </bpmn:definitions>
@@ -0,0 +1,31 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler" exporterVersion="52c6ff6" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.9.0">
3
+ <bpmn:process id="cluster_variable_tenant_updatable_string" name="Tenant Cluster Variable Updatable String" isExecutable="true">
4
+ <bpmn:startEvent id="StartEvent_1">
5
+ <bpmn:extensionElements>
6
+ <zeebe:ioMapping>
7
+ <zeebe:output source="=camunda.vars.tenant.UPDATABLE_APP_VERSION" target="APP_VERSION_VALUE" />
8
+ </zeebe:ioMapping>
9
+ </bpmn:extensionElements>
10
+ <bpmn:outgoing>Flow_1k9dndp</bpmn:outgoing>
11
+ </bpmn:startEvent>
12
+ <bpmn:sequenceFlow id="Flow_1k9dndp" sourceRef="StartEvent_1" targetRef="Event_1mc2ikr" />
13
+ <bpmn:endEvent id="Event_1mc2ikr">
14
+ <bpmn:incoming>Flow_1k9dndp</bpmn:incoming>
15
+ </bpmn:endEvent>
16
+ </bpmn:process>
17
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
18
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="cluster_variable_tenant_updatable_string">
19
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
20
+ <dc:Bounds x="179" y="159" width="36" height="36" />
21
+ </bpmndi:BPMNShape>
22
+ <bpmndi:BPMNShape id="Event_1mc2ikr_di" bpmnElement="Event_1mc2ikr">
23
+ <dc:Bounds x="312" y="159" width="36" height="36" />
24
+ </bpmndi:BPMNShape>
25
+ <bpmndi:BPMNEdge id="Flow_1k9dndp_di" bpmnElement="Flow_1k9dndp">
26
+ <di:waypoint x="215" y="177" />
27
+ <di:waypoint x="312" y="177" />
28
+ </bpmndi:BPMNEdge>
29
+ </bpmndi:BPMNPlane>
30
+ </bpmndi:BPMNDiagram>
31
+ </bpmn:definitions>
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
3
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
4
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
5
+ xmlns:zeebe="http://camunda.org/schema/zeebe/1.0"
6
+ xmlns:modeler="http://camunda.org/schema/modeler/1.0"
7
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1"
8
+ targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler"
9
+ exporterVersion="52c6ff6" modeler:executionPlatform="Camunda Cloud"
10
+ modeler:executionPlatformVersion="8.9.0">
11
+ <bpmn:process id="cluster_variable_tenant_original_string" name="Tenant Cluster Variable Original String"
12
+ isExecutable="true">
13
+ <bpmn:startEvent id="StartEvent_1">
14
+ <bpmn:extensionElements>
15
+ <zeebe:ioMapping>
16
+ <zeebe:output source="=camunda.vars.tenant.ORIGINAL_APP_VERSION" target="APP_VERSION_VALUE" />
17
+ </zeebe:ioMapping>
18
+ </bpmn:extensionElements>
19
+ <bpmn:outgoing>Flow_1k9dndp</bpmn:outgoing>
20
+ </bpmn:startEvent>
21
+ <bpmn:sequenceFlow id="Flow_1k9dndp" sourceRef="StartEvent_1" targetRef="Activity_1whhatc" />
22
+ <bpmn:endEvent id="Event_1mc2ikr">
23
+ <bpmn:incoming>Flow_0wixfng</bpmn:incoming>
24
+ </bpmn:endEvent>
25
+ <bpmn:sequenceFlow id="Flow_0wixfng" sourceRef="Activity_1whhatc" targetRef="Event_1mc2ikr" />
26
+ <bpmn:userTask id="Activity_1whhatc" name="Preview String tenant cluster variable">
27
+ <bpmn:extensionElements>
28
+ <zeebe:userTask />
29
+ <zeebe:formDefinition formId="Form_ClusterVarString" />
30
+ </bpmn:extensionElements>
31
+ <bpmn:incoming>Flow_1k9dndp</bpmn:incoming>
32
+ <bpmn:outgoing>Flow_0wixfng</bpmn:outgoing>
33
+ </bpmn:userTask>
34
+ </bpmn:process>
35
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
36
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="cluster_variable_tenant_original_string">
37
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
38
+ <dc:Bounds x="342" y="272" width="36" height="36" />
39
+ </bpmndi:BPMNShape>
40
+ <bpmndi:BPMNShape id="Event_1mc2ikr_di" bpmnElement="Event_1mc2ikr">
41
+ <dc:Bounds x="582" y="272" width="36" height="36" />
42
+ </bpmndi:BPMNShape>
43
+ <bpmndi:BPMNShape id="Activity_0lwojkk_di" bpmnElement="Activity_1whhatc">
44
+ <dc:Bounds x="430" y="250" width="100" height="80" />
45
+ <bpmndi:BPMNLabel />
46
+ </bpmndi:BPMNShape>
47
+ <bpmndi:BPMNEdge id="Flow_1k9dndp_di" bpmnElement="Flow_1k9dndp">
48
+ <di:waypoint x="378" y="290" />
49
+ <di:waypoint x="430" y="290" />
50
+ </bpmndi:BPMNEdge>
51
+ <bpmndi:BPMNEdge id="Flow_0wixfng_di" bpmnElement="Flow_0wixfng">
52
+ <di:waypoint x="530" y="290" />
53
+ <di:waypoint x="582" y="290" />
54
+ </bpmndi:BPMNEdge>
55
+ </bpmndi:BPMNPlane>
56
+ </bpmndi:BPMNDiagram>
57
+ </bpmn:definitions>
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const SM_8_9_1 = require("../../fixtures/SM-8.9");
4
+ const _setup_1 = require("../../test-setup.js");
5
+ const apiHelpers_1 = require("../../utils/apiHelpers");
6
+ const randomName_1 = require("../../utils/randomName");
7
+ const TENANT_ID = '<default>';
8
+ const TENANT_CLUSTER_VAR_NAMES = {
9
+ ORIGINAL_JSON: 'ORIGINAL_API_INFO',
10
+ UPDATABLE_JSON: 'UPDATABLE_API_INFO',
11
+ ORIGINAL_STRING: 'ORIGINAL_APP_VERSION',
12
+ UPDATABLE_STRING: 'UPDATABLE_APP_VERSION',
13
+ };
14
+ const clusterVariableJsonValue = process.env.CLUSTER_VARIABLE_JSON_VALUE || process.env.CLUSTER_VARIABLE_JSON;
15
+ const clusterVariableStringValue = process.env.CLUSTER_VARIABLE_STRING_VALUE || 'v1.0.0';
16
+ function getConfigByType(type) {
17
+ const configs = {
18
+ JSON: {
19
+ processName: 'Tenant Cluster Variable Original JSON',
20
+ processNameUpdatable: 'Tenant Cluster Variable Updatable JSON',
21
+ taskName: 'Preview JSON tenant cluster variables',
22
+ taskElementId: 'Activity_1whhatc',
23
+ originalVariableName: TENANT_CLUSTER_VAR_NAMES.ORIGINAL_JSON,
24
+ updatableVariableName: TENANT_CLUSTER_VAR_NAMES.UPDATABLE_JSON,
25
+ originalValue: originalJsonClusterVariableValue,
26
+ operateVariableName: 'URL',
27
+ randomValuePrefix: 'https://updated.tenant.api.com',
28
+ },
29
+ String: {
30
+ processName: 'Tenant Cluster Variable Original String',
31
+ processNameUpdatable: 'Tenant Cluster Variable Updatable String',
32
+ taskName: 'Preview String tenant cluster variable',
33
+ taskElementId: 'Activity_1whhatc',
34
+ originalVariableName: TENANT_CLUSTER_VAR_NAMES.ORIGINAL_STRING,
35
+ updatableVariableName: TENANT_CLUSTER_VAR_NAMES.UPDATABLE_STRING,
36
+ originalValue: originalStringClusterVariableValue,
37
+ operateVariableName: 'APP_VERSION_VALUE',
38
+ randomValuePrefix: 'v3.0.0-tenant-updated',
39
+ },
40
+ };
41
+ return configs[type];
42
+ }
43
+ let authToken;
44
+ let originalJsonClusterVariableValue;
45
+ let originalStringClusterVariableValue;
46
+ let jsonProcessKeyDisplay;
47
+ let jsonProcessKeyUpdate;
48
+ let stringProcessKeyDisplay;
49
+ let stringProcessKeyUpdate;
50
+ if (process.env.IS_MT === 'true') {
51
+ SM_8_9_1.test.describe.configure({ mode: 'parallel' });
52
+ SM_8_9_1.test.describe('Tenant-Scoped Cluster Variables User Flows', () => {
53
+ SM_8_9_1.test.beforeAll(async () => {
54
+ authToken = await (0, apiHelpers_1.authSmAPI)();
55
+ if (!clusterVariableJsonValue) {
56
+ throw new Error('Neither CLUSTER_VARIABLE_JSON_VALUE nor CLUSTER_VARIABLE_JSON env var is set');
57
+ }
58
+ const jsonValue = JSON.parse(clusterVariableJsonValue);
59
+ await Promise.all([
60
+ (0, apiHelpers_1.createTenantClusterVariable)(authToken, 'sm', TENANT_ID, TENANT_CLUSTER_VAR_NAMES.ORIGINAL_JSON, jsonValue),
61
+ (0, apiHelpers_1.createTenantClusterVariable)(authToken, 'sm', TENANT_ID, TENANT_CLUSTER_VAR_NAMES.UPDATABLE_JSON, jsonValue),
62
+ (0, apiHelpers_1.createTenantClusterVariable)(authToken, 'sm', TENANT_ID, TENANT_CLUSTER_VAR_NAMES.ORIGINAL_STRING, clusterVariableStringValue),
63
+ (0, apiHelpers_1.createTenantClusterVariable)(authToken, 'sm', TENANT_ID, TENANT_CLUSTER_VAR_NAMES.UPDATABLE_STRING, clusterVariableStringValue),
64
+ ]);
65
+ originalJsonClusterVariableValue = jsonValue;
66
+ originalStringClusterVariableValue = clusterVariableStringValue;
67
+ const deployments = [
68
+ {
69
+ path: './resources/cluster_variables/cluster_variable_tenant_json_readonly.bpmn',
70
+ assignTo: 'jsonProcessKeyDisplay',
71
+ },
72
+ {
73
+ path: './resources/cluster_variables/cluster_variable_tenant_json_mutable.bpmn',
74
+ assignTo: 'jsonProcessKeyUpdate',
75
+ },
76
+ {
77
+ path: './resources/cluster_variables/cluster_variable_json_form.form',
78
+ assignTo: null,
79
+ },
80
+ {
81
+ path: './resources/cluster_variables/cluster_variable_tenant_string_readonly.bpmn',
82
+ assignTo: 'stringProcessKeyDisplay',
83
+ },
84
+ {
85
+ path: './resources/cluster_variables/cluster_variable_tenant_string_mutable.bpmn',
86
+ assignTo: 'stringProcessKeyUpdate',
87
+ },
88
+ {
89
+ path: './resources/cluster_variables/cluster_variable_string_form.form',
90
+ assignTo: null,
91
+ },
92
+ ];
93
+ const deploymentResults = await Promise.all(deployments.map((d) => (0, apiHelpers_1.deployProcess)(d.path, authToken)));
94
+ jsonProcessKeyDisplay = deploymentResults[0];
95
+ jsonProcessKeyUpdate = deploymentResults[1];
96
+ stringProcessKeyDisplay = deploymentResults[3];
97
+ stringProcessKeyUpdate = deploymentResults[4];
98
+ });
99
+ SM_8_9_1.test.beforeEach(async ({ navigationPage }, testInfo) => {
100
+ await navigationPage.goToOperate((testInfo.workerIndex + 1) * 1000);
101
+ });
102
+ SM_8_9_1.test.afterEach(async ({ page }, testInfo) => {
103
+ await (0, _setup_1.captureScreenshot)(page, testInfo);
104
+ await (0, _setup_1.captureFailureVideo)(page, testInfo);
105
+ });
106
+ SM_8_9_1.test.describe('Tenant cluster variable', () => {
107
+ const testConfigs = [
108
+ {
109
+ type: 'JSON',
110
+ processKeyDisplay: () => jsonProcessKeyDisplay,
111
+ processKeyUpdate: () => jsonProcessKeyUpdate,
112
+ },
113
+ {
114
+ type: 'String',
115
+ processKeyDisplay: () => stringProcessKeyDisplay,
116
+ processKeyUpdate: () => stringProcessKeyUpdate,
117
+ },
118
+ ];
119
+ for (const config of testConfigs) {
120
+ (0, SM_8_9_1.test)(`User views ${config.type} tenant cluster variable in Tasklist from readonly process and completes task`, async ({ navigationPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskPanelPage, taskDetailsPage, }) => {
121
+ SM_8_9_1.test.slow();
122
+ const derived = getConfigByType(config.type);
123
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(config.processKeyDisplay()), authToken);
124
+ await SM_8_9_1.test.step('User can access the process on operate', async () => {
125
+ await operateHomePage.clickProcessesTab();
126
+ await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
127
+ await operateProcessesPage.clickProcessInstanceLink(String(instanceKey));
128
+ await operateProcessInstancePage.assertActiveTokenIsPresent();
129
+ });
130
+ await SM_8_9_1.test.step(`User can view the process with ${config.type} tenant cluster variable on tasklist`, async () => {
131
+ await navigationPage.goToTasklist();
132
+ await taskPanelPage.openTask(derived.taskName, true, derived.taskElementId);
133
+ await taskDetailsPage.clickAssignToMeButton();
134
+ });
135
+ await SM_8_9_1.test.step(`User can view the value of ${config.type} tenant cluster variable and complete the task`, async () => {
136
+ if (config.type === 'JSON') {
137
+ for (const value of Object.values(derived.originalValue)) {
138
+ await taskDetailsPage.assertTextIsPresent(String(value));
139
+ }
140
+ }
141
+ else {
142
+ await taskDetailsPage.assertTextIsPresent(String(derived.originalValue));
143
+ }
144
+ await taskDetailsPage.clickCompleteTaskButton();
145
+ });
146
+ await SM_8_9_1.test.step('User can assert the process is completed on Operate', async () => {
147
+ await navigationPage.goToOperate();
148
+ await operateHomePage.clickProcessesTab();
149
+ await operateProcessesPage.clickProcessCompletedCheckbox();
150
+ await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
151
+ await operateProcessesPage.clickProcessInstanceLink(String(instanceKey), 'completed');
152
+ await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
153
+ });
154
+ });
155
+ }
156
+ for (const config of testConfigs) {
157
+ (0, SM_8_9_1.test)(`User updates ${config.type} tenant cluster variable in Admin UI and verifies changes in Operate`, async ({ navigationPage, ocIdentityHomePage, ocIdentityClusterVariablesPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
158
+ SM_8_9_1.test.slow();
159
+ const derived = getConfigByType(config.type);
160
+ const randomRawValue = await (0, randomName_1.randomNameAgregator)(derived.randomValuePrefix);
161
+ const newValue = config.type === 'JSON'
162
+ ? JSON.stringify({
163
+ endpoint: randomRawValue,
164
+ timeout_ms: '5000',
165
+ array: ['updated_item1', 'updated_item2'],
166
+ })
167
+ : JSON.stringify(randomRawValue);
168
+ await SM_8_9_1.test.step('User navigates to Admin UI', async () => {
169
+ await navigationPage.goToOCIdentity();
170
+ });
171
+ await SM_8_9_1.test.step('User navigates to Cluster Variables tab', async () => {
172
+ await ocIdentityHomePage.clickClusterVariablesTab();
173
+ });
174
+ await SM_8_9_1.test.step(`User verifies ${config.type} tenant cluster variable exists`, async () => {
175
+ await ocIdentityClusterVariablesPage.assertVariableExists(derived.updatableVariableName, TENANT_ID);
176
+ });
177
+ await SM_8_9_1.test.step(`User updates the ${config.type} tenant cluster variable value`, async () => {
178
+ await ocIdentityClusterVariablesPage.editVariable(derived.updatableVariableName, newValue, TENANT_ID);
179
+ });
180
+ await SM_8_9_1.test.step(`User creates a process instance with the updated ${config.type} tenant cluster variable`, async () => {
181
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(config.processKeyUpdate()), authToken);
182
+ await SM_8_9_1.test.step('User navigates to the process instance on Operate', async () => {
183
+ await navigationPage.goToOperate();
184
+ await operateHomePage.clickProcessesTab();
185
+ await operateProcessesPage.clickProcessCompletedCheckbox();
186
+ await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
187
+ await operateProcessesPage.clickProcessInstanceLink(String(instanceKey), 'completed');
188
+ await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
189
+ });
190
+ await SM_8_9_1.test.step(`User verifies the updated ${config.type} tenant cluster variable value is present in process variables`, async () => {
191
+ await operateProcessInstancePage.assertProcessVariableContainsText(derived.operateVariableName, randomRawValue);
192
+ });
193
+ });
194
+ });
195
+ }
196
+ });
197
+ });
198
+ }
@@ -23,6 +23,7 @@ export declare function waitForOrchestrationClusterReady(managementUrl?: string,
23
23
  export declare function deployProcess(filePath: string, authToken?: string, environment?: 'saas' | 'sm', clusterType?: string): Promise<number | null>;
24
24
  export declare function createProcessInstance(processDefinitionKey: string, authToken?: string, environment?: 'saas' | 'sm', clusterType?: string, variables?: Record<string, unknown>): Promise<string>;
25
25
  export declare function waitForProcessInstanceVisible(processInstanceKey: string, authToken?: string, environment?: 'saas' | 'sm', clusterType?: string, maxAttempts?: number, retryDelayMs?: number): Promise<void>;
26
+ export declare function createTenantClusterVariable(authToken: string, environment: 'saas' | 'sm', tenantId: string, variableName: string, variableValue: unknown, clusterType?: string): Promise<void>;
26
27
  export declare function createJsonClusterVariable(authToken?: string, environment?: 'saas' | 'sm', customVariableName?: string, customVariableValue?: string, clusterType?: string): Promise<void>;
27
28
  export declare function createStringClusterVariable(authToken?: string, environment?: 'saas' | 'sm', customVariableName?: string, customVariableValue?: string, clusterType?: string): Promise<void>;
28
29
  interface ReportDefinition {
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.updateClusterDataFilters = exports.getClusterDataFilters = exports.getTestClusterUuid = exports.authConsoleManagementAPI = exports.updateCollectionScope = exports.createSingleProcessReport = exports.setOptimizeSharing = exports.createDashboard = exports.createCollection = exports.getOptimizeCookieSm = exports.getOptimizeCoockie = exports.loginToOptimizeSession = exports.createStringClusterVariable = exports.createJsonClusterVariable = exports.waitForProcessInstanceVisible = exports.createProcessInstance = exports.deployProcess = exports.waitForOrchestrationClusterReady = exports.waitForInboundWebhookRegistered = exports.waitForConnectorsReady = exports.validateMcpServerHealth = exports.authC8runAPI = exports.authSmAPI = exports.authSaasAPI = exports.authAPI = exports.buildZeebeApiUrl = exports.retryOnTransientApiError = exports.retryOn500 = exports.sendRequestAndAssertResponse = exports.assertUnauthorizedResponseBody = exports.expectUnauthorizedErrorBody = exports.assertResponseStatus = exports.getApiRequestContext = void 0;
6
+ exports.updateClusterDataFilters = exports.getClusterDataFilters = exports.getTestClusterUuid = exports.authConsoleManagementAPI = exports.updateCollectionScope = exports.createSingleProcessReport = exports.setOptimizeSharing = exports.createDashboard = exports.createCollection = exports.getOptimizeCookieSm = exports.getOptimizeCoockie = exports.loginToOptimizeSession = exports.createStringClusterVariable = exports.createJsonClusterVariable = exports.createTenantClusterVariable = exports.waitForProcessInstanceVisible = exports.createProcessInstance = exports.deployProcess = exports.waitForOrchestrationClusterReady = exports.waitForInboundWebhookRegistered = exports.waitForConnectorsReady = exports.validateMcpServerHealth = exports.authC8runAPI = exports.authSmAPI = exports.authSaasAPI = exports.authAPI = exports.buildZeebeApiUrl = exports.retryOnTransientApiError = exports.retryOn500 = exports.sendRequestAndAssertResponse = exports.assertUnauthorizedResponseBody = exports.expectUnauthorizedErrorBody = exports.assertResponseStatus = exports.getApiRequestContext = void 0;
7
7
  const test_1 = require("@playwright/test");
8
8
  const sleep_1 = require("./sleep");
9
9
  const randomSleep_1 = require("./randomSleep");
@@ -615,7 +615,7 @@ async function waitForProcessInstanceVisible(processInstanceKey, authToken, envi
615
615
  throw new Error(`Process instance ${processInstanceKey} was not visible in secondary storage after ${maxAttempts} attempts.`);
616
616
  }
617
617
  exports.waitForProcessInstanceVisible = waitForProcessInstanceVisible;
618
- async function createClusterVariableInternal(authToken, environment, variableName, variableValue, variableType, clusterType) {
618
+ async function createClusterVariableInternal(authToken, environment, variableName, variableValue, variableType, clusterType, endpointPath = '/v2/cluster-variables/global') {
619
619
  // Retry on transient ingress / upstream errors (502/503/504) and on
620
620
  // network-layer exceptions, which we have observed during nightly runs
621
621
  // when the orchestration cluster gateway is in the middle of a rollout.
@@ -626,7 +626,7 @@ async function createClusterVariableInternal(authToken, environment, variableNam
626
626
  let lastErrorMessage = '';
627
627
  try {
628
628
  apiRequestContext = await getApiRequestContext();
629
- const url = buildZeebeApiUrl('/v2/cluster-variables/global', environment, clusterType);
629
+ const url = buildZeebeApiUrl(endpointPath, environment, clusterType);
630
630
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
631
631
  let status;
632
632
  let bodyText = '';
@@ -683,6 +683,10 @@ async function createClusterVariableInternal(authToken, environment, variableNam
683
683
  throw new Error(`Unexpected error creating ${variableType} cluster variable "${variableName}": ${errorMessage}`);
684
684
  }
685
685
  }
686
+ async function createTenantClusterVariable(authToken, environment, tenantId, variableName, variableValue, clusterType) {
687
+ await createClusterVariableInternal(authToken, environment, variableName, variableValue, 'Tenant', clusterType, `/v2/cluster-variables/tenants/${encodeURIComponent(tenantId)}`);
688
+ }
689
+ exports.createTenantClusterVariable = createTenantClusterVariable;
686
690
  async function createJsonClusterVariable(authToken, environment = 'saas', customVariableName, customVariableValue, clusterType) {
687
691
  const variableName = customVariableName ?? String(process.env.CLUSTER_VARIABLE_NAME);
688
692
  const variableValue = customVariableValue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1228",
3
+ "version": "0.0.1230",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler" exporterVersion="52c6ff6" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.9.0">
3
+ <bpmn:process id="cluster_variable_tenant_updatable_json" name="Tenant Cluster Variable Updatable JSON" isExecutable="true">
4
+ <bpmn:startEvent id="StartEvent_1">
5
+ <bpmn:extensionElements>
6
+ <zeebe:ioMapping>
7
+ <zeebe:output source="=camunda.vars.tenant.UPDATABLE_API_INFO.endpoint" target="URL" />
8
+ <zeebe:output source="=camunda.vars.tenant.UPDATABLE_API_INFO.timeout_ms" target="TIMEOUT_MS" />
9
+ <zeebe:output source="=camunda.vars.tenant.UPDATABLE_API_INFO.array" target="ARRAY" />
10
+ </zeebe:ioMapping>
11
+ </bpmn:extensionElements>
12
+ <bpmn:outgoing>Flow_1k9dndp</bpmn:outgoing>
13
+ </bpmn:startEvent>
14
+ <bpmn:sequenceFlow id="Flow_1k9dndp" sourceRef="StartEvent_1" targetRef="Event_1mc2ikr" />
15
+ <bpmn:endEvent id="Event_1mc2ikr">
16
+ <bpmn:incoming>Flow_1k9dndp</bpmn:incoming>
17
+ </bpmn:endEvent>
18
+ </bpmn:process>
19
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
20
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="cluster_variable_tenant_updatable_json">
21
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
22
+ <dc:Bounds x="179" y="159" width="36" height="36" />
23
+ </bpmndi:BPMNShape>
24
+ <bpmndi:BPMNShape id="Event_1mc2ikr_di" bpmnElement="Event_1mc2ikr">
25
+ <dc:Bounds x="312" y="159" width="36" height="36" />
26
+ </bpmndi:BPMNShape>
27
+ <bpmndi:BPMNEdge id="Flow_1k9dndp_di" bpmnElement="Flow_1k9dndp">
28
+ <di:waypoint x="215" y="177" />
29
+ <di:waypoint x="312" y="177" />
30
+ </bpmndi:BPMNEdge>
31
+ </bpmndi:BPMNPlane>
32
+ </bpmndi:BPMNDiagram>
33
+ </bpmn:definitions>
@@ -0,0 +1,59 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
3
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
4
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
5
+ xmlns:zeebe="http://camunda.org/schema/zeebe/1.0"
6
+ xmlns:modeler="http://camunda.org/schema/modeler/1.0"
7
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1"
8
+ targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler"
9
+ exporterVersion="52c6ff6" modeler:executionPlatform="Camunda Cloud"
10
+ modeler:executionPlatformVersion="8.9.0">
11
+ <bpmn:process id="cluster_variable_tenant_original_json" name="Tenant Cluster Variable Original JSON"
12
+ isExecutable="true">
13
+ <bpmn:startEvent id="StartEvent_1">
14
+ <bpmn:extensionElements>
15
+ <zeebe:ioMapping>
16
+ <zeebe:output source="=camunda.vars.tenant.ORIGINAL_API_INFO.endpoint" target="URL" />
17
+ <zeebe:output source="=camunda.vars.tenant.ORIGINAL_API_INFO.timeout_ms" target="TIMEOUT_MS" />
18
+ <zeebe:output source="=camunda.vars.tenant.ORIGINAL_API_INFO.array" target="ARRAY" />
19
+ </zeebe:ioMapping>
20
+ </bpmn:extensionElements>
21
+ <bpmn:outgoing>Flow_1k9dndp</bpmn:outgoing>
22
+ </bpmn:startEvent>
23
+ <bpmn:sequenceFlow id="Flow_1k9dndp" sourceRef="StartEvent_1" targetRef="Activity_1whhatc" />
24
+ <bpmn:endEvent id="Event_1mc2ikr">
25
+ <bpmn:incoming>Flow_0wixfng</bpmn:incoming>
26
+ </bpmn:endEvent>
27
+ <bpmn:sequenceFlow id="Flow_0wixfng" sourceRef="Activity_1whhatc" targetRef="Event_1mc2ikr" />
28
+ <bpmn:userTask id="Activity_1whhatc" name="Preview JSON tenant cluster variables">
29
+ <bpmn:extensionElements>
30
+ <zeebe:userTask />
31
+ <zeebe:formDefinition formId="Form_ClusterVarJSON" />
32
+ </bpmn:extensionElements>
33
+ <bpmn:incoming>Flow_1k9dndp</bpmn:incoming>
34
+ <bpmn:outgoing>Flow_0wixfng</bpmn:outgoing>
35
+ </bpmn:userTask>
36
+ </bpmn:process>
37
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
38
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="cluster_variable_tenant_original_json">
39
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
40
+ <dc:Bounds x="342" y="272" width="36" height="36" />
41
+ </bpmndi:BPMNShape>
42
+ <bpmndi:BPMNShape id="Event_1mc2ikr_di" bpmnElement="Event_1mc2ikr">
43
+ <dc:Bounds x="582" y="272" width="36" height="36" />
44
+ </bpmndi:BPMNShape>
45
+ <bpmndi:BPMNShape id="Activity_0lwojkk_di" bpmnElement="Activity_1whhatc">
46
+ <dc:Bounds x="430" y="250" width="100" height="80" />
47
+ <bpmndi:BPMNLabel />
48
+ </bpmndi:BPMNShape>
49
+ <bpmndi:BPMNEdge id="Flow_1k9dndp_di" bpmnElement="Flow_1k9dndp">
50
+ <di:waypoint x="378" y="290" />
51
+ <di:waypoint x="430" y="290" />
52
+ </bpmndi:BPMNEdge>
53
+ <bpmndi:BPMNEdge id="Flow_0wixfng_di" bpmnElement="Flow_0wixfng">
54
+ <di:waypoint x="530" y="290" />
55
+ <di:waypoint x="582" y="290" />
56
+ </bpmndi:BPMNEdge>
57
+ </bpmndi:BPMNPlane>
58
+ </bpmndi:BPMNDiagram>
59
+ </bpmn:definitions>
@@ -0,0 +1,31 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:zeebe="http://camunda.org/schema/zeebe/1.0" xmlns:modeler="http://camunda.org/schema/modeler/1.0" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler" exporterVersion="52c6ff6" modeler:executionPlatform="Camunda Cloud" modeler:executionPlatformVersion="8.9.0">
3
+ <bpmn:process id="cluster_variable_tenant_updatable_string" name="Tenant Cluster Variable Updatable String" isExecutable="true">
4
+ <bpmn:startEvent id="StartEvent_1">
5
+ <bpmn:extensionElements>
6
+ <zeebe:ioMapping>
7
+ <zeebe:output source="=camunda.vars.tenant.UPDATABLE_APP_VERSION" target="APP_VERSION_VALUE" />
8
+ </zeebe:ioMapping>
9
+ </bpmn:extensionElements>
10
+ <bpmn:outgoing>Flow_1k9dndp</bpmn:outgoing>
11
+ </bpmn:startEvent>
12
+ <bpmn:sequenceFlow id="Flow_1k9dndp" sourceRef="StartEvent_1" targetRef="Event_1mc2ikr" />
13
+ <bpmn:endEvent id="Event_1mc2ikr">
14
+ <bpmn:incoming>Flow_1k9dndp</bpmn:incoming>
15
+ </bpmn:endEvent>
16
+ </bpmn:process>
17
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
18
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="cluster_variable_tenant_updatable_string">
19
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
20
+ <dc:Bounds x="179" y="159" width="36" height="36" />
21
+ </bpmndi:BPMNShape>
22
+ <bpmndi:BPMNShape id="Event_1mc2ikr_di" bpmnElement="Event_1mc2ikr">
23
+ <dc:Bounds x="312" y="159" width="36" height="36" />
24
+ </bpmndi:BPMNShape>
25
+ <bpmndi:BPMNEdge id="Flow_1k9dndp_di" bpmnElement="Flow_1k9dndp">
26
+ <di:waypoint x="215" y="177" />
27
+ <di:waypoint x="312" y="177" />
28
+ </bpmndi:BPMNEdge>
29
+ </bpmndi:BPMNPlane>
30
+ </bpmndi:BPMNDiagram>
31
+ </bpmn:definitions>
@@ -0,0 +1,57 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
3
+ xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
4
+ xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
5
+ xmlns:zeebe="http://camunda.org/schema/zeebe/1.0"
6
+ xmlns:modeler="http://camunda.org/schema/modeler/1.0"
7
+ xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1"
8
+ targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Web Modeler"
9
+ exporterVersion="52c6ff6" modeler:executionPlatform="Camunda Cloud"
10
+ modeler:executionPlatformVersion="8.9.0">
11
+ <bpmn:process id="cluster_variable_tenant_original_string" name="Tenant Cluster Variable Original String"
12
+ isExecutable="true">
13
+ <bpmn:startEvent id="StartEvent_1">
14
+ <bpmn:extensionElements>
15
+ <zeebe:ioMapping>
16
+ <zeebe:output source="=camunda.vars.tenant.ORIGINAL_APP_VERSION" target="APP_VERSION_VALUE" />
17
+ </zeebe:ioMapping>
18
+ </bpmn:extensionElements>
19
+ <bpmn:outgoing>Flow_1k9dndp</bpmn:outgoing>
20
+ </bpmn:startEvent>
21
+ <bpmn:sequenceFlow id="Flow_1k9dndp" sourceRef="StartEvent_1" targetRef="Activity_1whhatc" />
22
+ <bpmn:endEvent id="Event_1mc2ikr">
23
+ <bpmn:incoming>Flow_0wixfng</bpmn:incoming>
24
+ </bpmn:endEvent>
25
+ <bpmn:sequenceFlow id="Flow_0wixfng" sourceRef="Activity_1whhatc" targetRef="Event_1mc2ikr" />
26
+ <bpmn:userTask id="Activity_1whhatc" name="Preview String tenant cluster variable">
27
+ <bpmn:extensionElements>
28
+ <zeebe:userTask />
29
+ <zeebe:formDefinition formId="Form_ClusterVarString" />
30
+ </bpmn:extensionElements>
31
+ <bpmn:incoming>Flow_1k9dndp</bpmn:incoming>
32
+ <bpmn:outgoing>Flow_0wixfng</bpmn:outgoing>
33
+ </bpmn:userTask>
34
+ </bpmn:process>
35
+ <bpmndi:BPMNDiagram id="BPMNDiagram_1">
36
+ <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="cluster_variable_tenant_original_string">
37
+ <bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
38
+ <dc:Bounds x="342" y="272" width="36" height="36" />
39
+ </bpmndi:BPMNShape>
40
+ <bpmndi:BPMNShape id="Event_1mc2ikr_di" bpmnElement="Event_1mc2ikr">
41
+ <dc:Bounds x="582" y="272" width="36" height="36" />
42
+ </bpmndi:BPMNShape>
43
+ <bpmndi:BPMNShape id="Activity_0lwojkk_di" bpmnElement="Activity_1whhatc">
44
+ <dc:Bounds x="430" y="250" width="100" height="80" />
45
+ <bpmndi:BPMNLabel />
46
+ </bpmndi:BPMNShape>
47
+ <bpmndi:BPMNEdge id="Flow_1k9dndp_di" bpmnElement="Flow_1k9dndp">
48
+ <di:waypoint x="378" y="290" />
49
+ <di:waypoint x="430" y="290" />
50
+ </bpmndi:BPMNEdge>
51
+ <bpmndi:BPMNEdge id="Flow_0wixfng_di" bpmnElement="Flow_0wixfng">
52
+ <di:waypoint x="530" y="290" />
53
+ <di:waypoint x="582" y="290" />
54
+ </bpmndi:BPMNEdge>
55
+ </bpmndi:BPMNPlane>
56
+ </bpmndi:BPMNDiagram>
57
+ </bpmn:definitions>