@camunda/e2e-test-suite 0.0.1227 → 0.0.1229

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.
@@ -218,6 +218,7 @@ declare class ModelerCreatePage {
218
218
  embedForm(formName: string): Promise<void>;
219
219
  clickFirstPlaceRESTConnector(): Promise<void>;
220
220
  dismissCreatePad(): Promise<void>;
221
+ private isAuthenticationPanelOpen;
221
222
  private openAuthenticationPanel;
222
223
  setOAuthTokenEndpoint(elementToClick: Locator, endpoint: string, options?: {
223
224
  retries?: number;
@@ -324,8 +324,11 @@ class ModelerCreatePage {
324
324
  .getByText('zeebeClientId');
325
325
  this.variableAssignmentValueTextboxThirdVariable = page.locator('#bio-properties-panel-StartEvent_1-output-2-source div');
326
326
  this.firstPlaceRESTConnector = page.locator('g:nth-child(2) > .djs-element > .djs-hit');
327
+ // Scoped to the group header (not any div whose text is "Authentication")
328
+ // so its class list can be read: the header carries `open` exactly while
329
+ // the group is expanded, which openAuthenticationPanel keys on.
327
330
  this.authenticationPanel = page
328
- .locator('div')
331
+ .locator('.bio-properties-panel-group-header')
329
332
  .filter({ hasText: /^Authentication$/ })
330
333
  .first();
331
334
  this.templateNotFoundTag = page
@@ -1739,6 +1742,17 @@ class ModelerCreatePage {
1739
1742
  .waitFor({ state: 'hidden', timeout: 10000 })
1740
1743
  .catch(() => false);
1741
1744
  }
1745
+ async isAuthenticationPanelOpen() {
1746
+ const classes = await this.authenticationPanel
1747
+ .getAttribute('class', { timeout: 5000 })
1748
+ .catch(() => null);
1749
+ return (classes ?? '').split(/\s+/).includes('open');
1750
+ }
1751
+ // The header is a toggle, not an "open" button, and the properties panel
1752
+ // keeps a group's expanded state across element selections — so clicking it
1753
+ // unconditionally collapses a group that a previous element already opened.
1754
+ // Click only while `open` is absent, then wait for it to appear.
1755
+ //
1742
1756
  // The Authentication group is contributed by the REST connector element
1743
1757
  // template, so it renders only while the version the diagram pins in
1744
1758
  // zeebe:modelerTemplateVersion is among the element templates Web Modeler
@@ -1746,22 +1760,30 @@ class ModelerCreatePage {
1746
1760
  // "Template: Not found" and the group can never appear, so report that as
1747
1761
  // its own cause instead of a bare 60s click timeout.
1748
1762
  async openAuthenticationPanel() {
1749
- try {
1750
- await this.authenticationPanel.click({ timeout: 60000 });
1751
- }
1752
- catch (err) {
1753
- const templateMissing = await this.templateNotFoundTag
1754
- .isVisible()
1755
- .catch(() => false);
1756
- if (templateMissing) {
1757
- throw new Error('REST connector element template did not resolve for this element: ' +
1758
- 'the properties panel shows "Template: Not found", so its ' +
1759
- 'Authentication group never renders. The zeebe:modelerTemplateVersion ' +
1760
- 'pinned in the uploaded fixture is no longer one of the element ' +
1761
- 'template versions this Web Modeler offers — re-pin the fixture to ' +
1762
- 'the offered version.');
1763
+ for (let attempt = 1; attempt <= 3; attempt++) {
1764
+ if (await this.isAuthenticationPanelOpen()) {
1765
+ return;
1763
1766
  }
1764
- throw err;
1767
+ try {
1768
+ await this.authenticationPanel.click({ timeout: 60000 });
1769
+ }
1770
+ catch (err) {
1771
+ const templateMissing = await this.templateNotFoundTag
1772
+ .isVisible()
1773
+ .catch(() => false);
1774
+ if (templateMissing) {
1775
+ throw new Error('REST connector element template did not resolve for this element: ' +
1776
+ 'the properties panel shows "Template: Not found", so its ' +
1777
+ 'Authentication group never renders. The zeebe:modelerTemplateVersion ' +
1778
+ 'pinned in the uploaded fixture is no longer one of the element ' +
1779
+ 'template versions this Web Modeler offers — re-pin the fixture to ' +
1780
+ 'the offered version.');
1781
+ }
1782
+ throw err;
1783
+ }
1784
+ await (0, test_1.expect)(this.authenticationPanel)
1785
+ .toHaveClass(/(?:^|\s)open(?:\s|$)/, { timeout: 10000 })
1786
+ .catch(() => false);
1765
1787
  }
1766
1788
  }
1767
1789
  async setOAuthTokenEndpoint(elementToClick, endpoint, options) {
@@ -1792,14 +1814,16 @@ class ModelerCreatePage {
1792
1814
  let lastError;
1793
1815
  for (let attempt = 1; attempt <= retries; attempt++) {
1794
1816
  try {
1795
- await (0, test_1.expect)(this.oauthTokenEndpointInput).toBeVisible({ timeout: 3000 });
1796
- await this.oauthTokenEndpointInput.click({ timeout: 3000 });
1817
+ await (0, test_1.expect)(this.oauthTokenEndpointInput).toBeVisible({
1818
+ timeout: 10000,
1819
+ });
1820
+ await this.oauthTokenEndpointInput.click({ timeout: 10000 });
1797
1821
  await this.oauthTokenEndpointInput.fill(endpoint, { timeout: 30000 });
1798
1822
  return;
1799
1823
  }
1800
1824
  catch (err) {
1801
1825
  lastError = err;
1802
- await this.authenticationPanel.click({ timeout: 60000 });
1826
+ await this.openAuthenticationPanel();
1803
1827
  await (0, sleep_1.sleep)(settleMs);
1804
1828
  }
1805
1829
  }
@@ -546,17 +546,30 @@ async function modelAndRunConnectorsDocHandlingDiagram(modelerCreatePage, modele
546
546
  await page.reload();
547
547
  await page.waitForLoadState('networkidle');
548
548
  await modelerCreatePage.fillStartEventVariablesForDocHandling(zeebeUrl, zeebeClientId, zeebeClientSecret);
549
- await modelerCreatePage.setOAuthTokenEndpoint(page.locator('.djs-hit').first(), endpoint);
549
+ // bpmn-js reorders the canvas `<g>` groups as elements render and get
550
+ // selected, so `g:nth-child(N)` does not keep pointing at the task it was
551
+ // written for. Pin each shape by its BPMN id from the fixture instead: these
552
+ // are exactly the five REST tasks the fixture configures with
553
+ // `authentication.type = oauth-client-credentials-flow`, i.e. the ones that
554
+ // render an "OAuth 2.0 token endpoint" field. The sixth task
555
+ // (Activity_0jxgggi, "Download & store Image as 'doc' storage") is `noAuth`
556
+ // and has no such field.
557
+ const restTaskHit = (elementId) => page
558
+ .locator(`.djs-element[data-element-id="${elementId}"] .djs-hit`)
559
+ .first();
560
+ await modelerCreatePage.setOAuthTokenEndpoint(restTaskHit('Activity_0k0vloc'), endpoint);
550
561
  await (0, sleep_1.sleep)(2000);
551
- await modelerCreatePage.setOAuthTokenEndpoint(page.locator('g:nth-child(3) > .djs-element > .djs-hit'), endpoint);
562
+ await modelerCreatePage.setOAuthTokenEndpoint(restTaskHit('Activity_02hwevk'), endpoint);
552
563
  await (0, sleep_1.sleep)(2000);
553
- await modelerCreatePage.setOAuthTokenEndpoint(page.locator('g:nth-child(6) > .djs-element > .djs-hit'), endpoint);
564
+ await modelerCreatePage.setOAuthTokenEndpoint(restTaskHit('Activity_1oi90zl'), endpoint);
565
+ // The two parallel-branch tasks sit under the Details panel, so it has to be
566
+ // closed before their shape can be clicked and reopened afterwards.
554
567
  await (0, sleep_1.sleep)(2000);
555
568
  await modelerCreatePage.clickCloseDetailsPanel();
556
- await modelerCreatePage.setOAuthTokenEndpoint(page.locator('g:nth-child(7) > .djs-element > .djs-hit'), endpoint, { openPanel: true });
569
+ await modelerCreatePage.setOAuthTokenEndpoint(restTaskHit('Activity_0iyt4gv'), endpoint, { openPanel: true });
557
570
  await (0, sleep_1.sleep)(2000);
558
571
  await modelerCreatePage.clickCloseDetailsPanel();
559
- await modelerCreatePage.setOAuthTokenEndpoint(page.locator('g:nth-child(9) > .djs-element > .djs-hit'), endpoint, { openPanel: true });
572
+ await modelerCreatePage.setOAuthTokenEndpoint(restTaskHit('Activity_1oiegam'), endpoint, { openPanel: true });
560
573
  await (0, sleep_1.sleep)(2000);
561
574
  await modelerCreatePage.runProcessInstance('', tenant);
562
575
  }
@@ -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
  }
@@ -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
  }
@@ -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.1227",
3
+ "version": "0.0.1229",
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>