@camunda/e2e-test-suite 0.0.163 → 0.0.165

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.
Files changed (26) hide show
  1. package/dist/gremlin/bin/gremlin +3 -0
  2. package/dist/gremlin/dist/cli.js +30 -0
  3. package/dist/gremlin/dist/format/fixWithEslint.js +43 -0
  4. package/dist/gremlin/dist/format/formatWithPrettier.js +43 -0
  5. package/dist/gremlin/dist/generate/generateNegativeTestsFile.js +98 -0
  6. package/dist/gremlin/dist/generate/renderGeneratedSpecFile.js +94 -0
  7. package/dist/gremlin/dist/strategies/invalidInput/collectInvalidInputTestCases.js +243 -0
  8. package/dist/gremlin/dist/strategies/invalidInput/extractValidInputSchemaForField.js +132 -0
  9. package/dist/gremlin/dist/strategies/invalidInput/renderInvalidInputTest.js +92 -0
  10. package/dist/gremlin/dist/strategies/invalidInput/types.js +2 -0
  11. package/dist/pages/SM-8.9/FormJsPage.js +3 -1
  12. package/dist/pages/SM-8.9/OperateProcessInstancePage.d.ts +1 -0
  13. package/dist/pages/SM-8.9/OperateProcessInstancePage.js +3 -0
  14. package/dist/pages/SM-8.9/OperateProcessesPage.d.ts +4 -0
  15. package/dist/pages/SM-8.9/OperateProcessesPage.js +20 -0
  16. package/dist/pages/SM-8.9/TaskDetailsPage.d.ts +1 -0
  17. package/dist/pages/SM-8.9/TaskDetailsPage.js +19 -0
  18. package/dist/tests/8.8/agentic-ai-user-flows.spec.js +6 -6
  19. package/dist/tests/8.9/agentic-ai-user-flows.spec.js +8 -8
  20. package/dist/tests/8.9/cluster-variables.spec.js +4 -4
  21. package/dist/tests/8.9/console-user-flows.spec.js +2 -1
  22. package/dist/tests/SM-8.9/cluster-variables.spec.d.ts +1 -0
  23. package/dist/tests/SM-8.9/cluster-variables.spec.js +60 -0
  24. package/dist/utils/apiHelpers.d.ts +12 -7
  25. package/dist/utils/apiHelpers.js +181 -99
  26. package/package.json +8 -2
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractValidInputSchemaForField = void 0;
4
+ const ts_morph_1 = require("ts-morph");
5
+ function extractValidInputSchemaForField(args) {
6
+ const type = args.typeAtNode.getType();
7
+ const symbol = type.getSymbol();
8
+ const declarations = symbol?.getDeclarations() ?? [];
9
+ // Try to resolve to a class declaration (page object).
10
+ for (const decl of declarations) {
11
+ const classDecl = decl.asKind(ts_morph_1.SyntaxKind.ClassDeclaration);
12
+ if (!classDecl)
13
+ continue;
14
+ const schema = extractFromClassConstructorAssignment(classDecl, args.fieldName);
15
+ if (schema)
16
+ return schema;
17
+ }
18
+ // Fallback: if it's an intersection/anonymous type, we still might have class in base types.
19
+ const baseTypes = type.getBaseTypes();
20
+ for (const base of baseTypes) {
21
+ const baseSymbol = base.getSymbol();
22
+ const baseDecls = baseSymbol?.getDeclarations() ?? [];
23
+ for (const decl of baseDecls) {
24
+ const classDecl = decl.asKind(ts_morph_1.SyntaxKind.ClassDeclaration);
25
+ if (!classDecl)
26
+ continue;
27
+ const schema = extractFromClassConstructorAssignment(classDecl, args.fieldName);
28
+ if (schema)
29
+ return schema;
30
+ }
31
+ }
32
+ return null;
33
+ }
34
+ exports.extractValidInputSchemaForField = extractValidInputSchemaForField;
35
+ function extractFromClassConstructorAssignment(classDecl, fieldName) {
36
+ const ctor = classDecl.getConstructors()[0];
37
+ if (!ctor)
38
+ return null;
39
+ const assignments = ctor
40
+ .getDescendantsOfKind(ts_morph_1.SyntaxKind.BinaryExpression)
41
+ .filter((b) => b.getOperatorToken().getText() === '=')
42
+ .filter((b) => {
43
+ const left = b.getLeft();
44
+ return (ts_morph_1.Node.isPropertyAccessExpression(left) &&
45
+ left.getExpression().getText() === 'this' &&
46
+ left.getName() === fieldName);
47
+ });
48
+ for (const assignment of assignments) {
49
+ const right = assignment.getRight();
50
+ const obj = right.asKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
51
+ if (!obj)
52
+ continue;
53
+ const schema = extractSchemaFromObjectLiteral(obj);
54
+ if (schema)
55
+ return schema;
56
+ // Also allow schema to come from spreads in the literal.
57
+ const spreads = obj.getProperties().filter(ts_morph_1.Node.isSpreadAssignment);
58
+ for (const spread of spreads) {
59
+ const spreadExpr = spread.getExpression();
60
+ const schemaFromSpread = resolveSchemaFromExpression(spreadExpr);
61
+ if (schemaFromSpread)
62
+ return schemaFromSpread;
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+ function extractSchemaFromObjectLiteral(obj) {
68
+ for (const prop of obj.getProperties()) {
69
+ if (!ts_morph_1.Node.isPropertyAssignment(prop))
70
+ continue;
71
+ if (prop.getName() !== '_schema')
72
+ continue;
73
+ const schemaObj = prop.getInitializerIfKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
74
+ if (!schemaObj)
75
+ continue;
76
+ const minlength = getNumberProp(schemaObj, 'minlength');
77
+ const maxlength = getNumberProp(schemaObj, 'maxlength');
78
+ const violationEffect = getStringProp(schemaObj, 'violationEffect');
79
+ if (typeof minlength === 'number' &&
80
+ typeof maxlength === 'number' &&
81
+ typeof violationEffect === 'string') {
82
+ return {
83
+ _schema: {
84
+ minlength,
85
+ maxlength,
86
+ violationEffect: violationEffect,
87
+ },
88
+ };
89
+ }
90
+ }
91
+ return null;
92
+ }
93
+ function resolveSchemaFromExpression(expr) {
94
+ // Identifier -> variable initializer
95
+ if (ts_morph_1.Node.isIdentifier(expr)) {
96
+ const decl = expr.getDefinitions()[0]?.getDeclarationNode();
97
+ const varDecl = decl?.asKind(ts_morph_1.SyntaxKind.VariableDeclaration);
98
+ const init = varDecl?.getInitializerIfKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
99
+ if (init) {
100
+ return extractSchemaFromObjectLiteral(init);
101
+ }
102
+ }
103
+ // Inline object literals.
104
+ const inlineObj = expr.asKind(ts_morph_1.SyntaxKind.ObjectLiteralExpression);
105
+ if (inlineObj)
106
+ return extractSchemaFromObjectLiteral(inlineObj);
107
+ return null;
108
+ }
109
+ function getNumberProp(obj, name) {
110
+ const prop = obj.getProperty(name);
111
+ if (!prop || !ts_morph_1.Node.isPropertyAssignment(prop))
112
+ return null;
113
+ const init = prop.getInitializer();
114
+ if (!init)
115
+ return null;
116
+ const num = init.asKind(ts_morph_1.SyntaxKind.NumericLiteral);
117
+ if (num)
118
+ return Number(num.getText());
119
+ return null;
120
+ }
121
+ function getStringProp(obj, name) {
122
+ const prop = obj.getProperty(name);
123
+ if (!prop || !ts_morph_1.Node.isPropertyAssignment(prop))
124
+ return null;
125
+ const init = prop.getInitializer();
126
+ if (!init)
127
+ return null;
128
+ const str = init.asKind(ts_morph_1.SyntaxKind.StringLiteral);
129
+ if (str)
130
+ return str.getLiteralText();
131
+ return null;
132
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderInvalidInputTest = void 0;
4
+ const ts_morph_1 = require("ts-morph");
5
+ function renderInvalidInputTest(args) {
6
+ const assertion = renderViolationAssertion({
7
+ violationEffect: args.violationEffect,
8
+ pageObjectName: args.pageObjectName,
9
+ inputFieldName: args.inputFieldName,
10
+ originalCallback: args.originalCallback,
11
+ targetFillCall: args.targetFillCall,
12
+ });
13
+ const invalidConstName = `${args.inputFieldName}${args.kind === 'minlength' ? 'TooShort' : 'TooLong'}`;
14
+ const invalidLiteral = toSingleQuotedStringLiteral(args.invalidValue);
15
+ return (`test('${escapeSingleQuotes(args.testTitle)}', async (${args.testParams}) => {\n` +
16
+ ` const ${invalidConstName} = ${invalidLiteral};\n` +
17
+ `\n` +
18
+ `${indentLines(args.prefixStatements.replaceAll(invalidLiteral, invalidConstName), 2)}\n` +
19
+ `\n` +
20
+ `${indentLines(assertion, 2)}\n` +
21
+ `});`);
22
+ }
23
+ exports.renderInvalidInputTest = renderInvalidInputTest;
24
+ function renderViolationAssertion(args) {
25
+ switch (args.violationEffect) {
26
+ case 'ARIA_INVALID_STATE':
27
+ return [
28
+ `await ${args.pageObjectName}.${args.inputFieldName}.blur();`,
29
+ `await expect(${args.pageObjectName}.${args.inputFieldName}).toHaveAttribute('aria-invalid', 'true');`,
30
+ ].join('\n');
31
+ case 'BUTTON_DISABLED': {
32
+ const buttonProp = inferNextClickedButtonProperty({
33
+ originalCallback: args.originalCallback,
34
+ targetFillCall: args.targetFillCall,
35
+ pageObjectName: args.pageObjectName,
36
+ });
37
+ if (!buttonProp) {
38
+ return `// TODO(gremlin): schema says BUTTON_DISABLED, but no click*Button() call was found after the fill call to infer which button should be disabled.`;
39
+ }
40
+ return `await expect(${args.pageObjectName}.${buttonProp}).toBeDisabled();`;
41
+ }
42
+ case 'FAILURE':
43
+ // Best-effort: common pattern in page objects.
44
+ return `// TODO(gremlin): schema says FAILURE; add an assertion for the expected failure mode (e.g. error banner visible).`;
45
+ default:
46
+ return `// TODO(gremlin): unknown violationEffect: ${String(args.violationEffect)}`;
47
+ }
48
+ }
49
+ function inferNextClickedButtonProperty(args) {
50
+ const body = args.originalCallback.getBody().asKind(ts_morph_1.SyntaxKind.Block);
51
+ if (!body)
52
+ return null;
53
+ const statements = body.getStatements();
54
+ const targetStatement = statements.find((stmt) => stmt
55
+ .getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression)
56
+ .some((c) => c === args.targetFillCall));
57
+ if (!targetStatement)
58
+ return null;
59
+ const idx = statements.indexOf(targetStatement);
60
+ const after = statements.slice(idx + 1);
61
+ for (const stmt of after) {
62
+ const calls = stmt.getDescendantsOfKind(ts_morph_1.SyntaxKind.CallExpression);
63
+ for (const call of calls) {
64
+ const expr = call.getExpression();
65
+ if (!ts_morph_1.Node.isPropertyAccessExpression(expr))
66
+ continue;
67
+ if (expr.getExpression().getText() !== args.pageObjectName)
68
+ continue;
69
+ const method = expr.getName();
70
+ if (!method.startsWith('click') || !method.endsWith('Button'))
71
+ continue;
72
+ const suffix = method.slice('click'.length); // ContinueButton
73
+ if (!suffix)
74
+ continue;
75
+ return suffix[0].toLowerCase() + suffix.slice(1);
76
+ }
77
+ }
78
+ return null;
79
+ }
80
+ function indentLines(text, spaces) {
81
+ const prefix = ' '.repeat(spaces);
82
+ return text
83
+ .split('\n')
84
+ .map((line) => (line.trim().length === 0 ? line : prefix + line))
85
+ .join('\n');
86
+ }
87
+ function escapeSingleQuotes(value) {
88
+ return value.replaceAll("'", "\\'");
89
+ }
90
+ function toSingleQuotedStringLiteral(value) {
91
+ return `'${value.replaceAll('\\', '\\\\').replaceAll("'", "\\'")}'`;
92
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -22,7 +22,9 @@ class FormJsPage {
22
22
  this.generateFormButton = page.getByRole('button', { name: 'Generate form' });
23
23
  this.formEditor = page.getByLabel('Form Definition');
24
24
  this.filePicker = page.locator('button[data-field-type="filepicker"]');
25
- this.generalPanel = page.getByTitle('General').first();
25
+ this.generalPanel = this.generalPanel = page
26
+ .locator('[data-group-id="group-general"]')
27
+ .first();
26
28
  this.keyInput = page.getByRole('textbox', { name: 'key' });
27
29
  this.uploadMultipleFilesToggle = page.locator('div[data-entry-id="multiple"] .bio-properties-panel-toggle-switch__switcher');
28
30
  this.documentReferenceInput = page.getByRole('textbox', {
@@ -19,5 +19,6 @@ declare class OperateProcessInstancePage {
19
19
  assertEitherIncidentOrCompletedIconVisible(): Promise<string>;
20
20
  assertProcessCompleteStatusWithRetry(timeout?: number, maxRetries?: number): Promise<void>;
21
21
  assertProcessVariableContainsText(variableName: string, text: string): Promise<void>;
22
+ assertActiveTokenIsPresent(): Promise<void>;
22
23
  }
23
24
  export { OperateProcessInstancePage };
@@ -163,5 +163,8 @@ class OperateProcessInstancePage {
163
163
  }
164
164
  throw new Error(`Failed to assert variable ${variableName} after ${maxRetries} attempts.`);
165
165
  }
166
+ async assertActiveTokenIsPresent() {
167
+ await (0, test_1.expect)(this.activeIcon).toBeVisible({ timeout: 60000 });
168
+ }
166
169
  }
167
170
  exports.OperateProcessInstancePage = OperateProcessInstancePage;
@@ -9,6 +9,8 @@ declare class OperateProcessesPage {
9
9
  readonly processPageHeading: Locator;
10
10
  readonly noMatchingInstancesMessage: Locator;
11
11
  readonly processFinishedInstancesCheckbox: Locator;
12
+ readonly moreFiltersButton: Locator;
13
+ readonly processInstanceKeyTextBox: Locator;
12
14
  constructor(page: Page);
13
15
  private checkCheckbox;
14
16
  private uncheckCheckbox;
@@ -24,5 +26,7 @@ declare class OperateProcessesPage {
24
26
  clickFinishedProcessInstancesCheckbox(): Promise<void>;
25
27
  clickProcessInstanceLink(processName: string, type?: 'active' | 'completed'): Promise<void>;
26
28
  clickProcessInstanceLinkWithPartialNameMatch(processName: string): Promise<void>;
29
+ private getMoreFilterValueLocator;
30
+ applyMoreFilters(filter: string, value: string): Promise<void>;
27
31
  }
28
32
  export { OperateProcessesPage };
@@ -15,6 +15,8 @@ class OperateProcessesPage {
15
15
  processPageHeading;
16
16
  noMatchingInstancesMessage;
17
17
  processFinishedInstancesCheckbox;
18
+ moreFiltersButton;
19
+ processInstanceKeyTextBox;
18
20
  constructor(page) {
19
21
  this.page = page;
20
22
  this.processResultCount = page.getByTestId('result-count');
@@ -37,6 +39,8 @@ class OperateProcessesPage {
37
39
  this.processFinishedInstancesCheckbox = page
38
40
  .getByTestId('filter-finished-instances')
39
41
  .getByRole('checkbox');
42
+ this.moreFiltersButton = page.getByRole('button', { name: 'More filters' });
43
+ this.processInstanceKeyTextBox = page.locator('#ids');
40
44
  }
41
45
  async checkCheckbox(checkbox) {
42
46
  if (!(await checkbox.isChecked())) {
@@ -181,5 +185,21 @@ class OperateProcessesPage {
181
185
  }
182
186
  throw new Error(`Failed to click on process instance link containing "${processName}" after ${maxRetries} attempts.`);
183
187
  }
188
+ getMoreFilterValueLocator(filter) {
189
+ switch (filter.trim()) {
190
+ case 'Process Instance Key(s)':
191
+ return this.processInstanceKeyTextBox;
192
+ default:
193
+ throw new Error(`Unsupported filter: "${filter}". Add a mapping in getMoreFilterValueLocator().`);
194
+ }
195
+ }
196
+ async applyMoreFilters(filter, value) {
197
+ await this.moreFiltersButton.click();
198
+ await this.page.getByRole('menuitem', { name: filter }).click();
199
+ const valueInput = this.getMoreFilterValueLocator(filter);
200
+ await (0, test_1.expect)(valueInput).toBeVisible({ timeout: 10000 });
201
+ await valueInput.fill(value);
202
+ await (0, sleep_1.sleep)(2000);
203
+ }
184
204
  }
185
205
  exports.OperateProcessesPage = OperateProcessesPage;
@@ -65,5 +65,6 @@ declare class TaskDetailsPage {
65
65
  assertLoadedImage(documentName: string): Promise<void>;
66
66
  assertDocumentDownloadButton(documentName: string): Promise<void>;
67
67
  assertPdfPreviewViewerExists(): Promise<void>;
68
+ assertTextIsPresent(expectedText: string): Promise<void>;
68
69
  }
69
70
  export { TaskDetailsPage };
@@ -243,5 +243,24 @@ class TaskDetailsPage {
243
243
  .locator('.fjs-documentPreview-pdf-viewer');
244
244
  await (0, test_1.expect)(firstPdfViewer.or(lastPdfViewer)).toBeVisible();
245
245
  }
246
+ async assertTextIsPresent(expectedText) {
247
+ const maxAttempts = 3;
248
+ let attempts = 0;
249
+ while (attempts < maxAttempts) {
250
+ try {
251
+ await (0, test_1.expect)(this.page.getByText(expectedText)).toBeVisible({
252
+ timeout: 60000,
253
+ });
254
+ return;
255
+ }
256
+ catch (error) {
257
+ attempts++;
258
+ if (attempts >= maxAttempts) {
259
+ throw error;
260
+ }
261
+ await this.page.reload();
262
+ }
263
+ }
264
+ }
246
265
  }
247
266
  exports.TaskDetailsPage = TaskDetailsPage;
@@ -48,8 +48,8 @@ _8_8_1.test.describe('Agentic Orchestation User Flows', () => {
48
48
  _8_8_1.test.beforeAll(async () => {
49
49
  authToken = await (0, apiHelpers_1.authSaasAPI)();
50
50
  await Promise.all([
51
- (0, apiHelpers_1.deployProcessSaaS)('./resources/agentic_ai/ai-agent-chat-user-feedback.form', authToken),
52
- (0, apiHelpers_1.deployProcessSaaS)('./resources/connectors/db_vector_connector/db-vector-retrieve-data.form', authToken),
51
+ (0, apiHelpers_1.deployProcess)('./resources/agentic_ai/ai-agent-chat-user-feedback.form', authToken),
52
+ (0, apiHelpers_1.deployProcess)('./resources/connectors/db_vector_connector/db-vector-retrieve-data.form', authToken),
53
53
  ]);
54
54
  await (0, sleep_1.sleep)(5000);
55
55
  });
@@ -66,11 +66,11 @@ _8_8_1.test.describe('Agentic Orchestation User Flows', () => {
66
66
  for (const params of aiAgentTestCases) {
67
67
  (0, _8_8_1.test)(`AI agent with tools provides feedback to user - ${params.provider}`, async ({ appsPage, operateHomePage, operateProcessInstancePage, operateProcessesPage, taskPanelPage, taskDetailsPage, }) => {
68
68
  _8_8_1.test.slow();
69
- const processKey = await (0, apiHelpers_1.deployProcessSaaS)(params.bpmnPath, authToken);
69
+ const processKey = await (0, apiHelpers_1.deployProcess)(params.bpmnPath, authToken);
70
70
  if (processKey == null) {
71
71
  throw new Error('Failed to deploy process or missing processDefinitionKey');
72
72
  }
73
- const instanceKey = await (0, apiHelpers_1.createProcessInstanceSaaS)(String(processKey), authToken);
73
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(processKey), authToken);
74
74
  await _8_8_1.test.step('User can access the process on operate', async () => {
75
75
  await operateHomePage.clickProcessesTab();
76
76
  await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
@@ -105,11 +105,11 @@ _8_8_1.test.describe('Agentic Orchestation User Flows', () => {
105
105
  for (const params of dbVectorTestCases) {
106
106
  (0, _8_8_1.test)(`DB Vector connector embed via ${params.embedding_provider} and stored on ${params.embedding_store} with source as plain text`, async ({ appsPage, operateHomePage, operateProcessInstancePage, operateProcessesPage, taskPanelPage, taskDetailsPage, }) => {
107
107
  _8_8_1.test.slow();
108
- const processKey = await (0, apiHelpers_1.deployProcessSaaS)(params.bpmnPath, authToken);
108
+ const processKey = await (0, apiHelpers_1.deployProcess)(params.bpmnPath, authToken);
109
109
  if (processKey == null) {
110
110
  throw new Error('Failed to deploy process or missing processDefinitionKey');
111
111
  }
112
- const instanceKey = await (0, apiHelpers_1.createProcessInstanceSaaS)(String(processKey), authToken);
112
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(processKey), authToken);
113
113
  await _8_8_1.test.step('User can access the process on operate', async () => {
114
114
  await operateHomePage.clickProcessesTab();
115
115
  await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
@@ -54,8 +54,8 @@ _8_9_1.test.describe('Agentic Orchestation User Flows', () => {
54
54
  _8_9_1.test.beforeAll(async () => {
55
55
  authToken = await (0, apiHelpers_1.authSaasAPI)();
56
56
  await Promise.all([
57
- (0, apiHelpers_1.deployProcessSaaS)('./resources/agentic_ai/ai-agent-chat-user-feedback.form', authToken),
58
- (0, apiHelpers_1.deployProcessSaaS)('./resources/connectors/db_vector_connector/db-vector-retrieve-data.form', authToken),
57
+ (0, apiHelpers_1.deployProcess)('./resources/agentic_ai/ai-agent-chat-user-feedback.form', authToken),
58
+ (0, apiHelpers_1.deployProcess)('./resources/connectors/db_vector_connector/db-vector-retrieve-data.form', authToken),
59
59
  ]);
60
60
  await (0, sleep_1.sleep)(5000);
61
61
  });
@@ -72,11 +72,11 @@ _8_9_1.test.describe('Agentic Orchestation User Flows', () => {
72
72
  for (const params of aiAgentTestCases) {
73
73
  (0, _8_9_1.test)(`AI agent with tools provides feedback to user - ${params.provider}`, async ({ appsPage, operateHomePage, operateProcessInstancePage, operateProcessesPage, taskPanelPage, taskDetailsPage, }) => {
74
74
  _8_9_1.test.slow();
75
- const processKey = await (0, apiHelpers_1.deployProcessSaaS)(params.bpmnPath, authToken);
75
+ const processKey = await (0, apiHelpers_1.deployProcess)(params.bpmnPath, authToken);
76
76
  if (processKey == null) {
77
77
  throw new Error('Failed to deploy process or missing processDefinitionKey');
78
78
  }
79
- const instanceKey = await (0, apiHelpers_1.createProcessInstanceSaaS)(String(processKey), authToken);
79
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(processKey), authToken);
80
80
  await _8_9_1.test.step('User can access the process on operate', async () => {
81
81
  await operateHomePage.clickProcessesTab();
82
82
  await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
@@ -111,11 +111,11 @@ _8_9_1.test.describe('Agentic Orchestation User Flows', () => {
111
111
  for (const params of aiAgentSubProcessTestCases) {
112
112
  (0, _8_9_1.test)(`AI agent sub process with tools provides feedback to user - ${params.provider}`, async ({ appsPage, operateHomePage, operateProcessInstancePage, operateProcessesPage, taskPanelPage, taskDetailsPage, }) => {
113
113
  _8_9_1.test.slow();
114
- const processKey = await (0, apiHelpers_1.deployProcessSaaS)(params.bpmnPath, authToken);
114
+ const processKey = await (0, apiHelpers_1.deployProcess)(params.bpmnPath, authToken);
115
115
  if (processKey == null) {
116
116
  throw new Error('Failed to deploy process or missing processDefinitionKey');
117
117
  }
118
- const instanceKey = await (0, apiHelpers_1.createProcessInstanceSaaS)(String(processKey), authToken);
118
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(processKey), authToken);
119
119
  await _8_9_1.test.step('User can access the process on operate', async () => {
120
120
  await operateHomePage.clickProcessesTab();
121
121
  await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
@@ -150,11 +150,11 @@ _8_9_1.test.describe('Agentic Orchestation User Flows', () => {
150
150
  for (const params of dbVectorTestCases) {
151
151
  (0, _8_9_1.test)(`DB Vector connector embed via ${params.embedding_provider} and stored on ${params.embedding_store} with source as plain text`, async ({ appsPage, operateHomePage, operateProcessInstancePage, operateProcessesPage, taskPanelPage, taskDetailsPage, }) => {
152
152
  _8_9_1.test.slow();
153
- const processKey = await (0, apiHelpers_1.deployProcessSaaS)(params.bpmnPath, authToken);
153
+ const processKey = await (0, apiHelpers_1.deployProcess)(params.bpmnPath, authToken);
154
154
  if (processKey == null) {
155
155
  throw new Error('Failed to deploy process or missing processDefinitionKey');
156
156
  }
157
- const instanceKey = await (0, apiHelpers_1.createProcessInstanceSaaS)(String(processKey), authToken);
157
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(processKey), authToken);
158
158
  await _8_9_1.test.step('User can access the process on operate', async () => {
159
159
  await operateHomePage.clickProcessesTab();
160
160
  await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
@@ -14,7 +14,7 @@ _8_9_1.test.describe('Cluster Variables User Flows', () => {
14
14
  const clusterName = 'Test Cluster';
15
15
  _8_9_1.test.beforeAll(async () => {
16
16
  authToken = await (0, apiHelpers_1.authSaasAPI)();
17
- await (0, apiHelpers_1.createGlobalClusterVariableSaaS)(authToken);
17
+ await (0, apiHelpers_1.createGlobalClusterVariable)(authToken);
18
18
  jsonClusterVariableValue = JSON.parse(process.env.CLUSTER_VARIABLE_JSON);
19
19
  });
20
20
  _8_9_1.test.beforeEach(async ({ page, appsPage, loginPage }, testInfo) => {
@@ -30,13 +30,13 @@ _8_9_1.test.describe('Cluster Variables User Flows', () => {
30
30
  (0, _8_9_1.test)('User deploys a process and accesses global cluster variable on Tasklist', async ({ appsPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskPanelPage, taskDetailsPage, }) => {
31
31
  _8_9_1.test.slow();
32
32
  const [processKey] = await Promise.all([
33
- (0, apiHelpers_1.deployProcessSaaS)('./resources/cluster_variables/cluster_variable_global_scope.bpmn', authToken),
34
- (0, apiHelpers_1.deployProcessSaaS)('./resources/cluster_variables/preview_cluster_variables.form', authToken),
33
+ (0, apiHelpers_1.deployProcess)('./resources/cluster_variables/cluster_variable_global_scope.bpmn', authToken),
34
+ (0, apiHelpers_1.deployProcess)('./resources/cluster_variables/preview_cluster_variables.form', authToken),
35
35
  ]);
36
36
  if (processKey == null) {
37
37
  throw new Error('Failed to deploy process or missing processDefinitionKey');
38
38
  }
39
- const instanceKey = await (0, apiHelpers_1.createProcessInstanceSaaS)(String(processKey), authToken);
39
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(processKey), authToken);
40
40
  await _8_9_1.test.step('User can access the process on operate', async () => {
41
41
  await operateHomePage.clickProcessesTab();
42
42
  await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
@@ -65,7 +65,8 @@ _8_9_1.test.describe('Console User Flow Tests @tasklistV2', () => {
65
65
  await (0, UtilitiesPage_1.assertLocatorVisibleWithRetry)(operateTabProcessInstancePage, operateTabProcessInstancePage.completedIcon, 'completed icon in Operate', 60000);
66
66
  });
67
67
  });
68
- (0, _8_9_1.test)('Alert Trigger Flow - Email Notification', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, clusterPage, clusterDetailsPage, connectorSettingsPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
68
+ //Waiting infra team to provide DNS configuration for email testing, skipping for now
69
+ _8_9_1.test.skip('Alert Trigger Flow - Email Notification', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, clusterPage, clusterDetailsPage, connectorSettingsPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
69
70
  _8_9_1.test.slow();
70
71
  const processName = 'Email_Alert_Process' + (await (0, _setup_1.generateRandomStringAsync)(3));
71
72
  const invalidURl = 'https://invalid';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,60 @@
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
+ let authToken;
7
+ let jsonClusterVariableValue;
8
+ SM_8_9_1.test.describe.configure({ mode: 'parallel' });
9
+ SM_8_9_1.test.describe('Cluster Variables User Flows', () => {
10
+ SM_8_9_1.test.beforeAll(async () => {
11
+ authToken = await (0, apiHelpers_1.authSmAPI)();
12
+ await (0, apiHelpers_1.createGlobalClusterVariable)(authToken);
13
+ jsonClusterVariableValue = JSON.parse(process.env.CLUSTER_VARIABLE_JSON);
14
+ });
15
+ SM_8_9_1.test.beforeEach(async ({ navigationPage }, testInfo) => {
16
+ await navigationPage.goToOperate((testInfo.workerIndex + 1) * 1000);
17
+ });
18
+ SM_8_9_1.test.afterEach(async ({ page }, testInfo) => {
19
+ await (0, _setup_1.captureScreenshot)(page, testInfo);
20
+ await (0, _setup_1.captureFailureVideo)(page, testInfo);
21
+ });
22
+ SM_8_9_1.test.describe('Global cluster variable', () => {
23
+ (0, SM_8_9_1.test)('User deploys a process and accesses global cluster variable on Tasklist', async ({ operateHomePage, operateProcessesPage, operateProcessInstancePage, navigationPage, taskPanelPage, taskDetailsPage, }) => {
24
+ SM_8_9_1.test.slow();
25
+ const [processKey] = await Promise.all([
26
+ (0, apiHelpers_1.deployProcess)('./resources/cluster_variables/cluster_variable_global_scope.bpmn', authToken),
27
+ (0, apiHelpers_1.deployProcess)('./resources/cluster_variables/preview_cluster_variables.form', authToken),
28
+ ]);
29
+ if (processKey == null) {
30
+ throw new Error('Failed to deploy process or missing processDefinitionKey');
31
+ }
32
+ const instanceKey = await (0, apiHelpers_1.createProcessInstance)(String(processKey), authToken);
33
+ await SM_8_9_1.test.step('User can access the process on operate', async () => {
34
+ await operateHomePage.clickProcessesTab();
35
+ await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
36
+ await operateProcessesPage.clickProcessInstanceLink(`Cluster Variable Global scope - API INFO`);
37
+ await operateProcessInstancePage.assertActiveTokenIsPresent();
38
+ });
39
+ await SM_8_9_1.test.step('User can view the process with cluster variables on tasklist', async () => {
40
+ await navigationPage.goToTasklist();
41
+ await taskPanelPage.openTask(`Preview cluster variables form`);
42
+ await taskDetailsPage.clickAssignToMeButton();
43
+ });
44
+ await SM_8_9_1.test.step('User can view the values of cluster variables and complete the task', async () => {
45
+ for (const [, value] of Object.entries(jsonClusterVariableValue)) {
46
+ await taskDetailsPage.assertTextIsPresent(String(value));
47
+ }
48
+ await taskDetailsPage.clickCompleteTaskButton();
49
+ });
50
+ await SM_8_9_1.test.step('User can assert the process is completed on Operate', async () => {
51
+ await navigationPage.goToOperate();
52
+ await operateHomePage.clickProcessesTab();
53
+ await operateProcessesPage.clickProcessCompletedCheckbox();
54
+ await operateProcessesPage.applyMoreFilters('Process Instance Key(s)', String(instanceKey));
55
+ await operateProcessesPage.clickProcessInstanceLink(`Cluster Variable Global scope - API INFO`);
56
+ await operateProcessInstancePage.assertProcessCompleteStatusWithRetry();
57
+ });
58
+ });
59
+ });
60
+ });
@@ -1,6 +1,18 @@
1
1
  /// <reference types="node" />
2
2
  import { APIRequestContext, APIResponse, Response, Page } from '@playwright/test';
3
3
  import { Serializable } from 'playwright-core/types/structs';
4
+ export declare function assertResponseStatus(response: APIResponse | Response, status: number): Promise<void>;
5
+ export declare function sendRequestAndAssertResponse(request: APIRequestContext, url: string, requestBody?: string | Buffer | Serializable, maxRetries?: number): Promise<void>;
6
+ export declare function authAPI(environment: 'saas'): Promise<string>;
7
+ export declare function authAPI(environment: 'sm'): Promise<string>;
8
+ export declare function authAPI(environment: 'saas', audience?: string): Promise<string>;
9
+ export declare function authAPI(environment: 'sm', audience?: string): Promise<string>;
10
+ export declare function authSaasAPI(audience?: string): Promise<string>;
11
+ export declare function authSmAPI(): Promise<string>;
12
+ export declare function authC8runAPI(name: string, password: string): Promise<void>;
13
+ export declare function deployProcess(filePath: string, authToken?: string, environment?: 'saas' | 'sm'): Promise<number | null>;
14
+ export declare function createProcessInstance(processDefinitionKey: string, authToken?: string, environment?: 'saas' | 'sm'): Promise<string>;
15
+ export declare function createGlobalClusterVariable(authToken?: string, environment?: 'saas' | 'sm'): Promise<void>;
4
16
  interface ReportDefinition {
5
17
  key: string;
6
18
  filter?: unknown[];
@@ -18,10 +30,6 @@ interface CreateSingleProcessReportOptions {
18
30
  definitions?: ReportDefinition[];
19
31
  configuration?: Record<string, unknown>;
20
32
  }
21
- export declare function authC8runAPI(name: string, password: string): Promise<void>;
22
- export declare function assertResponseStatus(response: APIResponse | Response, status: number): Promise<void>;
23
- export declare function sendRequestAndAssertResponse(request: APIRequestContext, url: string, requestBody?: string | Buffer | Serializable, maxRetries?: number): Promise<void>;
24
- export declare function authSaasAPI(audience?: string): Promise<string>;
25
33
  export declare function getOptimizeCoockie(page: Page): Promise<string>;
26
34
  export declare function createCollection(request: APIRequestContext, options: {
27
35
  name: string;
@@ -42,7 +50,4 @@ export declare function updateCollectionScope(request: APIRequestContext, option
42
50
  tenants: string[];
43
51
  }>;
44
52
  }): Promise<unknown>;
45
- export declare function deployProcessSaaS(filePath: string, authToken?: string): Promise<number | null>;
46
- export declare function createProcessInstanceSaaS(processDefinitionKey: string, authToken?: string): Promise<string>;
47
- export declare function createGlobalClusterVariableSaaS(authToken?: string): Promise<void>;
48
53
  export {};