@camunda/e2e-test-suite 0.0.1426 → 0.0.1428

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.
@@ -44,6 +44,7 @@ const OCIdentityClusterVariablesPage_1 = require("../pages/8.10/OCIdentityCluste
44
44
  const ClientCredentialsDetailsPage_1 = require("../pages/8.10/ClientCredentialsDetailsPage");
45
45
  const AuditLogPage_1 = require("../pages/8.10/AuditLogPage");
46
46
  const DataFiltersPage_1 = require("../pages/8.10/DataFiltersPage");
47
+ const hubBundleCopy_1 = require("../utils/hubBundleCopy");
47
48
  const test = test_1.test.extend({
48
49
  makeAxeBuilder: async ({ page }, use) => {
49
50
  const makeAxeBuilder = () => new playwright_1.default({ page }).withTags([
@@ -193,6 +194,7 @@ const test = test_1.test.extend({
193
194
  },
194
195
  body: '',
195
196
  }));
197
+ await (0, hubBundleCopy_1.serveHubBundleFromCopy)(context);
196
198
  await use();
197
199
  },
198
200
  {
@@ -44,6 +44,7 @@ const OCIdentityClusterVariablesPage_1 = require("../pages/8.11/OCIdentityCluste
44
44
  const ClientCredentialsDetailsPage_1 = require("../pages/8.11/ClientCredentialsDetailsPage");
45
45
  const AuditLogPage_1 = require("../pages/8.11/AuditLogPage");
46
46
  const DataFiltersPage_1 = require("../pages/8.11/DataFiltersPage");
47
+ const hubBundleCopy_1 = require("../utils/hubBundleCopy");
47
48
  const test = test_1.test.extend({
48
49
  makeAxeBuilder: async ({ page }, use) => {
49
50
  const makeAxeBuilder = () => new playwright_1.default({ page }).withTags([
@@ -193,6 +194,7 @@ const test = test_1.test.extend({
193
194
  },
194
195
  body: '',
195
196
  }));
197
+ await (0, hubBundleCopy_1.serveHubBundleFromCopy)(context);
196
198
  await use();
197
199
  },
198
200
  {
@@ -35,6 +35,7 @@ const PlayPage_1 = require("../pages/8.7/PlayPage");
35
35
  const ConnectorTemplatePage_1 = require("../pages/8.7/ConnectorTemplatePage");
36
36
  const IdpCreatePage_1 = require("../pages/8.7/IdpCreatePage");
37
37
  const ClientCredentialsDetailsPage_1 = require("../pages/8.7/ClientCredentialsDetailsPage");
38
+ const hubBundleCopy_1 = require("../utils/hubBundleCopy");
38
39
  const test = test_1.test.extend({
39
40
  makeAxeBuilder: async ({ page }, use) => {
40
41
  const makeAxeBuilder = () => new playwright_1.default({ page }).withTags([
@@ -156,6 +157,7 @@ const test = test_1.test.extend({
156
157
  },
157
158
  body: '',
158
159
  }));
160
+ await (0, hubBundleCopy_1.serveHubBundleFromCopy)(context);
159
161
  await use();
160
162
  },
161
163
  {
@@ -40,6 +40,7 @@ const OCIdentityMappingRulesPage_1 = require("../pages/8.8/OCIdentityMappingRule
40
40
  const OCIdentityRolesPage_1 = require("../pages/8.8/OCIdentityRolesPage");
41
41
  const OCIdentityAuthorizationsPage_1 = require("../pages/8.8/OCIdentityAuthorizationsPage");
42
42
  const ClientCredentialsDetailsPage_1 = require("../pages/8.8/ClientCredentialsDetailsPage");
43
+ const hubBundleCopy_1 = require("../utils/hubBundleCopy");
43
44
  const test = test_1.test.extend({
44
45
  makeAxeBuilder: async ({ page }, use) => {
45
46
  const makeAxeBuilder = () => new playwright_1.default({ page }).withTags([
@@ -177,6 +178,7 @@ const test = test_1.test.extend({
177
178
  },
178
179
  body: '',
179
180
  }));
181
+ await (0, hubBundleCopy_1.serveHubBundleFromCopy)(context);
180
182
  await use();
181
183
  },
182
184
  {
@@ -41,6 +41,7 @@ const OCIdentityRolesPage_1 = require("../pages/8.9/OCIdentityRolesPage");
41
41
  const OCIdentityAuthorizationsPage_1 = require("../pages/8.9/OCIdentityAuthorizationsPage");
42
42
  const OCIdentityClusterVariablesPage_1 = require("../pages/8.9/OCIdentityClusterVariablesPage");
43
43
  const ClientCredentialsDetailsPage_1 = require("../pages/8.9/ClientCredentialsDetailsPage");
44
+ const hubBundleCopy_1 = require("../utils/hubBundleCopy");
44
45
  const test = test_1.test.extend({
45
46
  makeAxeBuilder: async ({ page }, use) => {
46
47
  const makeAxeBuilder = () => new playwright_1.default({ page }).withTags([
@@ -181,6 +182,7 @@ const test = test_1.test.extend({
181
182
  },
182
183
  body: '',
183
184
  }));
185
+ await (0, hubBundleCopy_1.serveHubBundleFromCopy)(context);
184
186
  await use();
185
187
  },
186
188
  {
@@ -5,4 +5,4 @@ export declare function navigateToApp(page: Page, appName: string): Promise<void
5
5
  export declare function openUserTaskOfProcessInstance(page: Page, request: APIRequestContext, processInstanceKey: string, maxRetries?: number, retryDelayMs?: number): Promise<string>;
6
6
  export declare function assertLocatorVisibleWithRetry(page: Page, locator: Locator, text: string, timeout?: number, maxRetries?: number): Promise<void>;
7
7
  export declare function validateURL(page: Page, URL: RegExp): Promise<void>;
8
- export declare function completeTaskWithRetry(taskPanelPage: TaskPanelPage, taskDetailsPage: TaskDetailsPage, taskName: string, taskPriority: string, userTaskName?: string, textInput?: string, maxRetries?: number): Promise<void>;
8
+ export declare function completeTaskWithRetry(taskPanelPage: TaskPanelPage, taskDetailsPage: TaskDetailsPage, taskName: string, taskPriority: string, userTaskName?: string, textInput?: string, maxRetries?: number, openTask?: () => Promise<string>): Promise<void>;
@@ -68,10 +68,10 @@ async function validateURL(page, URL) {
68
68
  (0, test_1.expect)(page).toHaveURL(URL);
69
69
  }
70
70
  exports.validateURL = validateURL;
71
- async function completeTaskWithRetry(taskPanelPage, taskDetailsPage, taskName, taskPriority, userTaskName = '', textInput = '', maxRetries = 5) {
71
+ async function completeTaskWithRetry(taskPanelPage, taskDetailsPage, taskName, taskPriority, userTaskName = '', textInput = '', maxRetries = 5, openTask = () => taskPanelPage.openTask(taskName, userTaskName)) {
72
72
  for (let attempt = 0; attempt < maxRetries; attempt++) {
73
73
  try {
74
- const userTaskKey = await taskPanelPage.openTask(taskName, userTaskName);
74
+ const userTaskKey = await openTask();
75
75
  await (0, sleep_1.sleep)(500);
76
76
  if (!(await taskDetailsPage.assignedToMeText.isVisible())) {
77
77
  await taskDetailsPage.clickAssignToMeButton();
@@ -11,6 +11,8 @@ const _setup_1 = require("../../test-setup.js");
11
11
  // the same process -- another worker, a --repeat-each copy, a leftover from an
12
12
  // earlier run -- can no longer be picked up by mistake.
13
13
  let variableEditingInstanceKey;
14
+ let zeebeUserTaskInstanceKey;
15
+ let formUserTaskInstanceKey;
14
16
  c8Run_8_10_1.test.beforeAll(async () => {
15
17
  await Promise.all([
16
18
  (0, zeebeClient_1.deploy)('./resources/User_Task_Editing_Variables.bpmn'),
@@ -20,7 +22,7 @@ c8Run_8_10_1.test.beforeAll(async () => {
20
22
  (0, zeebeClient_1.deploy)('./resources/Start_Form_Process.bpmn'),
21
23
  (0, zeebeClient_1.deploy)('./resources/Zeebe_User_Task_Process_With_Priority.bpmn'),
22
24
  ]);
23
- const [, variableEditingInstances] = await Promise.all([
25
+ const [zeebeUserTaskInstances, variableEditingInstances, formInstances] = await Promise.all([
24
26
  (0, zeebeClient_1.createInstances)('Zeebe_User_Task', 1, 1),
25
27
  (0, zeebeClient_1.createInstances)('User_Task_Editing_Variables', 1, 1, {
26
28
  testVariable: 'testValue',
@@ -30,6 +32,8 @@ c8Run_8_10_1.test.beforeAll(async () => {
30
32
  (0, zeebeClient_1.createInstances)('Zeebe_User_Task_Process_With_Priority', 1, 1),
31
33
  ]);
32
34
  variableEditingInstanceKey = String(variableEditingInstances[0].processInstanceKey);
35
+ zeebeUserTaskInstanceKey = String(zeebeUserTaskInstances[0].processInstanceKey);
36
+ formUserTaskInstanceKey = String(formInstances[0].processInstanceKey);
33
37
  await (0, sleep_1.sleep)(5000);
34
38
  });
35
39
  c8Run_8_10_1.test.describe('HTO User Flow Tests', () => {
@@ -80,23 +84,23 @@ c8Run_8_10_1.test.describe('HTO User Flow Tests', () => {
80
84
  await taskDetailsPage.clickCompleteTaskButton();
81
85
  });
82
86
  });
83
- (0, c8Run_8_10_1.test)('Form.js Integration with User Task', async ({ taskDetailsPage, taskPanelPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskListLoginPage, operateLoginPage, page, }) => {
87
+ (0, c8Run_8_10_1.test)('Form.js Integration with User Task', async ({ request, taskDetailsPage, taskPanelPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskListLoginPage, operateLoginPage, page, }) => {
84
88
  await c8Run_8_10_1.test.step('View Process Instance in Operate and complete User Task in Tasklist', async () => {
85
89
  await (0, UtilitiesPage_1.navigateToApp)(page, 'operate');
86
90
  await operateLoginPage.login('demo', 'demo');
87
91
  await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 180000 });
88
92
  await operateHomePage.clickProcessesTab();
89
- await operateProcessesPage.clickProcessInstanceLink('Form_User_Task_3');
93
+ await operateProcessesPage.clickProcessInstanceLink('Form_User_Task_3', formUserTaskInstanceKey);
90
94
  await operateProcessInstancePage.activeIconAssertion();
91
95
  await (0, UtilitiesPage_1.navigateToApp)(page, 'tasklist');
92
96
  await taskListLoginPage.login('demo', 'demo');
93
- await (0, UtilitiesPage_1.completeTaskWithRetry)(taskPanelPage, taskDetailsPage, 'Form_User_Task_3', 'Medium', 'Activity_1hj42el', 'Test User');
97
+ await (0, UtilitiesPage_1.completeTaskWithRetry)(taskPanelPage, taskDetailsPage, 'Form_User_Task_3', 'Medium', 'Activity_1hj42el', 'Test User', 5, () => (0, UtilitiesPage_1.openUserTaskOfProcessInstance)(page, request, formUserTaskInstanceKey));
94
98
  await (0, UtilitiesPage_1.navigateToApp)(page, 'operate');
95
99
  await operateLoginPage.login('demo', 'demo');
96
100
  await operateHomePage.clickProcessesTab();
97
101
  await operateProcessesPage.clickProcessCompletedCheckbox();
98
102
  await (0, sleep_1.sleep)(1000);
99
- await operateProcessesPage.clickProcessInstanceLink('Form_User_Task_3');
103
+ await operateProcessesPage.clickProcessInstanceLink('Form_User_Task_3', formUserTaskInstanceKey);
100
104
  await operateProcessInstancePage.completedIconAssertion();
101
105
  });
102
106
  });
@@ -112,25 +116,25 @@ c8Run_8_10_1.test.describe('HTO User Flow Tests', () => {
112
116
  await operateProcessInstancePage.completedIconAssertion();
113
117
  });
114
118
  });
115
- (0, c8Run_8_10_1.test)('Zeebe User Task User Flow', async ({ page, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskDetailsPage, taskPanelPage, operateLoginPage, taskListLoginPage, }) => {
119
+ (0, c8Run_8_10_1.test)('Zeebe User Task User Flow', async ({ page, request, operateHomePage, operateProcessesPage, operateProcessInstancePage, taskDetailsPage, taskPanelPage, operateLoginPage, taskListLoginPage, }) => {
116
120
  await c8Run_8_10_1.test.step('View Process Instance in Operate, complete User Task in Tasklist', async () => {
117
121
  await (0, UtilitiesPage_1.navigateToApp)(page, 'operate');
118
122
  await operateLoginPage.login('demo', 'demo');
119
123
  await operateHomePage.clickProcessesTab();
120
- await operateProcessesPage.clickProcessInstanceLink('Zeebe_User_Task');
124
+ await operateProcessesPage.clickProcessInstanceLink('Zeebe_User_Task', zeebeUserTaskInstanceKey);
121
125
  await operateProcessInstancePage.activeIconAssertion();
122
126
  await (0, UtilitiesPage_1.navigateToApp)(page, 'tasklist');
123
127
  await taskListLoginPage.login('demo', 'demo');
124
128
  await (0, test_1.expect)(page.getByText('Zeebe_User_Task').first()).toBeVisible({
125
129
  timeout: 60000,
126
130
  });
127
- await (0, UtilitiesPage_1.completeTaskWithRetry)(taskPanelPage, taskDetailsPage, 'Zeebe_User_Task', 'Medium');
131
+ await (0, UtilitiesPage_1.completeTaskWithRetry)(taskPanelPage, taskDetailsPage, 'Zeebe_User_Task', 'Medium', '', '', 5, () => (0, UtilitiesPage_1.openUserTaskOfProcessInstance)(page, request, zeebeUserTaskInstanceKey));
128
132
  await (0, UtilitiesPage_1.navigateToApp)(page, 'operate');
129
133
  await operateLoginPage.login('demo', 'demo');
130
134
  await (0, test_1.expect)(operateHomePage.processesTab).toBeVisible({ timeout: 120000 });
131
135
  await operateHomePage.clickProcessesTab();
132
136
  await operateProcessesPage.clickProcessCompletedCheckbox();
133
- await operateProcessesPage.clickProcessInstanceLink('Zeebe_User_Task');
137
+ await operateProcessesPage.clickProcessInstanceLink('Zeebe_User_Task', zeebeUserTaskInstanceKey);
134
138
  await operateProcessInstancePage.completedIconAssertion();
135
139
  });
136
140
  });
@@ -0,0 +1,19 @@
1
+ import type { BrowserContext } from '@playwright/test';
2
+ /**
3
+ * Serves Hub's app.js from a per-worker copy instead of downloading it on
4
+ * every page load.
5
+ *
6
+ * Hub's app.js is ~8.3 MB compressed and keeps one URL across releases, so a
7
+ * normal browser keeps it in its disk cache and only revalidates it. Test
8
+ * contexts cannot: the Osano routes turn their HTTP cache off, and their
9
+ * in-memory cache drops any file over 6.25 MiB within seconds anyway. Every
10
+ * Hub page load in a SaaS test therefore downloaded the whole bundle, which
11
+ * was most of the INT data transfer these tests cause.
12
+ *
13
+ * Each worker keeps the bundle it last downloaded and sends Hub the same
14
+ * If-Modified-Since request a browser would: a 304 is answered from the copy,
15
+ * a 200 (a new Hub release) replaces it. Pages always run the bundle Hub
16
+ * currently serves.
17
+ */
18
+ export declare const HUB_BUNDLE_URL: RegExp;
19
+ export declare function serveHubBundleFromCopy(context: BrowserContext, url?: RegExp): Promise<void>;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.serveHubBundleFromCopy = exports.HUB_BUNDLE_URL = void 0;
4
+ /**
5
+ * Serves Hub's app.js from a per-worker copy instead of downloading it on
6
+ * every page load.
7
+ *
8
+ * Hub's app.js is ~8.3 MB compressed and keeps one URL across releases, so a
9
+ * normal browser keeps it in its disk cache and only revalidates it. Test
10
+ * contexts cannot: the Osano routes turn their HTTP cache off, and their
11
+ * in-memory cache drops any file over 6.25 MiB within seconds anyway. Every
12
+ * Hub page load in a SaaS test therefore downloaded the whole bundle, which
13
+ * was most of the INT data transfer these tests cause.
14
+ *
15
+ * Each worker keeps the bundle it last downloaded and sends Hub the same
16
+ * If-Modified-Since request a browser would: a 304 is answered from the copy,
17
+ * a 200 (a new Hub release) replaces it. Pages always run the bundle Hub
18
+ * currently serves.
19
+ */
20
+ exports.HUB_BUNDLE_URL = /^https:\/\/hub\.[^/]+\/app\.js(\?.*)?$/;
21
+ const copies = new Map();
22
+ // The fetched body is already decoded, so these headers of the original
23
+ // response no longer describe it.
24
+ const DROPPED_HEADERS = new Set([
25
+ 'content-encoding',
26
+ 'content-length',
27
+ 'transfer-encoding',
28
+ ]);
29
+ async function answerFromCopy(route) {
30
+ const request = route.request();
31
+ const url = request.url();
32
+ const copy = copies.get(url);
33
+ const headers = { ...request.headers() };
34
+ if (copy) {
35
+ headers['if-modified-since'] = copy.lastModified;
36
+ }
37
+ const response = await route.fetch({ headers });
38
+ if (response.status() === 304 && copy) {
39
+ await route.fulfill({ status: 200, headers: copy.headers, body: copy.body });
40
+ return;
41
+ }
42
+ const lastModified = response.headers()['last-modified'];
43
+ if (response.status() !== 200 || !lastModified) {
44
+ await route.fulfill({ response });
45
+ return;
46
+ }
47
+ const kept = {};
48
+ for (const [name, value] of Object.entries(response.headers())) {
49
+ if (!DROPPED_HEADERS.has(name.toLowerCase())) {
50
+ kept[name] = value;
51
+ }
52
+ }
53
+ const body = await response.body();
54
+ copies.set(url, { lastModified, headers: kept, body });
55
+ console.log(`[hub-bundle-copy] pid=${process.pid} downloaded ${url} ` +
56
+ `(Last-Modified ${lastModified})`);
57
+ await route.fulfill({ status: 200, headers: kept, body });
58
+ }
59
+ async function serveHubBundleFromCopy(context, url = exports.HUB_BUNDLE_URL) {
60
+ await context.route(url, async (route) => {
61
+ try {
62
+ await answerFromCopy(route);
63
+ }
64
+ catch (error) {
65
+ console.warn(`[hub-bundle-copy] falling back to the network: ${String(error).split('\n')[0]}`);
66
+ await route.continue().catch(() => { });
67
+ }
68
+ });
69
+ }
70
+ exports.serveHubBundleFromCopy = serveHubBundleFromCopy;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camunda/e2e-test-suite",
3
- "version": "0.0.1426",
3
+ "version": "0.0.1428",
4
4
  "description": "End-to-end test helpers for Camunda 8",
5
5
  "repository": {
6
6
  "type": "git",