@camunda/e2e-test-suite 0.0.1001 → 0.0.1003
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.
- package/dist/pages/8.10/ModelerCreatePage.d.ts +3 -0
- package/dist/pages/8.10/ModelerCreatePage.js +47 -4
- package/dist/pages/8.7/ModelerCreatePage.d.ts +13 -0
- package/dist/pages/8.7/ModelerCreatePage.js +30 -8
- package/dist/tests/8.10/hto-user-flows.spec.js +1 -4
- package/dist/tests/8.10/optimize-sharing-alerts-export-api.spec.js +11 -4
- package/dist/tests/8.10/smoke-tests.spec.js +1 -4
- package/dist/utils/apiHelpers.d.ts +1 -0
- package/dist/utils/apiHelpers.js +10 -2
- package/dist/utils/constants.js +6 -2
- package/package.json +1 -1
|
@@ -41,6 +41,8 @@ declare class ModelerCreatePage {
|
|
|
41
41
|
readonly firstPlacedElement: Locator;
|
|
42
42
|
readonly secondPlacedElement: Locator;
|
|
43
43
|
readonly appendElementButton: Locator;
|
|
44
|
+
readonly appendElementIndicator: Locator;
|
|
45
|
+
readonly appendCreatePad: Locator;
|
|
44
46
|
readonly payloadInput: Locator;
|
|
45
47
|
readonly marketPlaceButton: Locator;
|
|
46
48
|
readonly publicHolidayConnectorOption: Locator;
|
|
@@ -178,6 +180,7 @@ declare class ModelerCreatePage {
|
|
|
178
180
|
clickFirstPlacedElement(): Promise<void>;
|
|
179
181
|
clickSecondPlacedElement(): Promise<void>;
|
|
180
182
|
clickSecondElement(): Promise<void>;
|
|
183
|
+
private openAppendCreatePad;
|
|
181
184
|
clickAppendElementButton(): Promise<void>;
|
|
182
185
|
clickMarketPlaceButton(): Promise<void>;
|
|
183
186
|
clickPublicHolidayConnectorOption(): Promise<void>;
|
|
@@ -47,6 +47,8 @@ class ModelerCreatePage {
|
|
|
47
47
|
firstPlacedElement;
|
|
48
48
|
secondPlacedElement;
|
|
49
49
|
appendElementButton;
|
|
50
|
+
appendElementIndicator;
|
|
51
|
+
appendCreatePad;
|
|
50
52
|
payloadInput;
|
|
51
53
|
marketPlaceButton;
|
|
52
54
|
publicHolidayConnectorOption;
|
|
@@ -118,9 +120,22 @@ class ModelerCreatePage {
|
|
|
118
120
|
this.generalPanel = page.locator('[data-group-id="group-general"]');
|
|
119
121
|
this.processIdInput = page.getByLabel('ID', { exact: true });
|
|
120
122
|
this.startEventElement = page.locator('.djs-hit').first();
|
|
123
|
+
// Match on the individual classes rather than the whole `class` attribute:
|
|
124
|
+
// an exact `[class="..."]` match breaks the moment bpmn-js reorders or adds
|
|
125
|
+
// a class, and it is the same shape camunda-hub's own e2e uses
|
|
126
|
+
// (`.djs-append-create-pad` + an `open` class assertion).
|
|
121
127
|
this.appendElementButton = page
|
|
122
|
-
.locator('
|
|
128
|
+
.locator('.djs-append-create-pad.open')
|
|
123
129
|
.first();
|
|
130
|
+
// improved-canvas 1.11.0 (camunda-hub fe2b961, 2026-08-25) stopped
|
|
131
|
+
// auto-opening the append create pad for an element that already has an
|
|
132
|
+
// outgoing sequence flow. Such an element now only carries a "+" append
|
|
133
|
+
// indicator overlay; moving the pointer onto it swaps the create pad in at
|
|
134
|
+
// the same spot, which is what reveals the append entries.
|
|
135
|
+
this.appendElementIndicator = page
|
|
136
|
+
.locator('.djs-append-indicator.selected')
|
|
137
|
+
.first();
|
|
138
|
+
this.appendCreatePad = page.locator('.djs-append-create-pad').first();
|
|
124
139
|
this.appendTaskButton = page.getByRole('button', { name: 'Append task' });
|
|
125
140
|
this.changeTypeButton = page.getByRole('button', {
|
|
126
141
|
name: 'Change element',
|
|
@@ -539,7 +554,7 @@ class ModelerCreatePage {
|
|
|
539
554
|
else if (parentElement == 'parallelGateway') {
|
|
540
555
|
await this.clickSecondPlacedGateway();
|
|
541
556
|
}
|
|
542
|
-
await this.
|
|
557
|
+
await this.clickAppendElementButton();
|
|
543
558
|
await this.appendEndEventButton.click({ timeout: 120000 });
|
|
544
559
|
}
|
|
545
560
|
}
|
|
@@ -893,6 +908,13 @@ class ModelerCreatePage {
|
|
|
893
908
|
await this.endEventCanvas.click({ timeout: 60000 });
|
|
894
909
|
}
|
|
895
910
|
async clickConnectToOtherElementButton() {
|
|
911
|
+
// 'Connect to other element' is a create-pad entry
|
|
912
|
+
// (`data-entry-id="connect"`), so the pad has to be open and hovered before
|
|
913
|
+
// the entry exists at all. The user task this is called on already has an
|
|
914
|
+
// outgoing sequence flow, so the pad no longer auto-opens — go through the
|
|
915
|
+
// append indicator first, which is exactly what clickAppendElementButton
|
|
916
|
+
// does (with its own retries).
|
|
917
|
+
await this.clickAppendElementButton();
|
|
896
918
|
await (0, test_1.expect)(this.connectToOtherElementButton).toBeVisible({
|
|
897
919
|
timeout: 60000,
|
|
898
920
|
});
|
|
@@ -909,11 +931,30 @@ class ModelerCreatePage {
|
|
|
909
931
|
await (0, test_1.expect)(this.secondElement).toBeVisible({ timeout: 60000 });
|
|
910
932
|
await this.secondElement.click({ timeout: 60000 });
|
|
911
933
|
}
|
|
934
|
+
// The append create pad only auto-opens for an element with no outgoing
|
|
935
|
+
// sequence flow. Every other selected element gets the "+" append indicator
|
|
936
|
+
// overlay instead, and the pad is rendered only once the pointer hovers it —
|
|
937
|
+
// which is exactly what appending a second parallel branch off an
|
|
938
|
+
// already-connected gateway needs.
|
|
939
|
+
async openAppendCreatePad() {
|
|
940
|
+
const padOpen = await this.appendElementButton
|
|
941
|
+
.isVisible()
|
|
942
|
+
.catch(() => false);
|
|
943
|
+
if (padOpen)
|
|
944
|
+
return;
|
|
945
|
+
// Force past the actionability check on both hops: the indicator is
|
|
946
|
+
// replaced by the create pad the moment the pointer reaches it, so an
|
|
947
|
+
// unforced click/hover is reported as "intercepted by the create pad" and
|
|
948
|
+
// then as "element is not visible" once the swap has happened.
|
|
949
|
+
await this.appendElementIndicator.hover({ force: true, timeout: 10000 });
|
|
950
|
+
await this.appendCreatePad.hover({ force: true, timeout: 10000 });
|
|
951
|
+
}
|
|
912
952
|
async clickAppendElementButton() {
|
|
913
953
|
const maxRetries = 3;
|
|
914
954
|
for (let retries = 0; retries < maxRetries; retries++) {
|
|
915
955
|
try {
|
|
916
956
|
await this.page.waitForTimeout(1000);
|
|
957
|
+
await this.openAppendCreatePad();
|
|
917
958
|
await (0, test_1.expect)(this.appendElementButton).toBeVisible({ timeout: 10000 });
|
|
918
959
|
await this.appendElementButton.hover({ force: true });
|
|
919
960
|
return;
|
|
@@ -1123,7 +1164,9 @@ class ModelerCreatePage {
|
|
|
1123
1164
|
async clickFirstPlacedGateway() {
|
|
1124
1165
|
try {
|
|
1125
1166
|
await this.firstPlacedGateway.click({ timeout: 60000 });
|
|
1126
|
-
|
|
1167
|
+
// The split gateway already has an outgoing flow, so selecting it renders
|
|
1168
|
+
// the append indicator rather than an open create pad — accept either.
|
|
1169
|
+
await (0, test_1.expect)(this.appendElementButton.or(this.appendElementIndicator)).toBeVisible({ timeout: 60000 });
|
|
1127
1170
|
}
|
|
1128
1171
|
catch (error) {
|
|
1129
1172
|
await this.page.reload();
|
|
@@ -1159,7 +1202,7 @@ class ModelerCreatePage {
|
|
|
1159
1202
|
await this.page.reload();
|
|
1160
1203
|
await (0, sleep_1.sleep)(20000);
|
|
1161
1204
|
await this.clickFirstPlacedElement();
|
|
1162
|
-
await this.
|
|
1205
|
+
await this.clickAppendElementButton();
|
|
1163
1206
|
}
|
|
1164
1207
|
await this.clickAppendGatewayButton();
|
|
1165
1208
|
await this.clickChangeTypeButton();
|
|
@@ -36,6 +36,7 @@ declare class ModelerCreatePage {
|
|
|
36
36
|
readonly firstPlacedElement: Locator;
|
|
37
37
|
readonly secondPlacedElement: Locator;
|
|
38
38
|
readonly appendElementButton: Locator;
|
|
39
|
+
readonly appendIndicator: Locator;
|
|
39
40
|
readonly payloadInput: Locator;
|
|
40
41
|
readonly marketPlaceButton: Locator;
|
|
41
42
|
readonly publicHolidayConnectorOption: Locator;
|
|
@@ -164,6 +165,18 @@ declare class ModelerCreatePage {
|
|
|
164
165
|
clickFirstPlacedElement(): Promise<void>;
|
|
165
166
|
clickSecondPlacedElement(): Promise<void>;
|
|
166
167
|
clickSecondElement(): Promise<void>;
|
|
168
|
+
/**
|
|
169
|
+
* Hovers the append ("+") pad of the current selection, opening it first
|
|
170
|
+
* when it is not already on screen.
|
|
171
|
+
*
|
|
172
|
+
* Since camunda/improved-canvas commit 3e2aa7a ("show append indicator
|
|
173
|
+
* instead of full pad when selection has outgoing flow") the full append pad
|
|
174
|
+
* only auto-opens for elements without an outgoing sequence flow. A selected
|
|
175
|
+
* element that already has one now shows a `.djs-append-indicator` "+"
|
|
176
|
+
* whose `mouseenter` opens the pad — see
|
|
177
|
+
* `lib/bpmn/appendIndicator/AppendIndicator.js` in that repo.
|
|
178
|
+
*/
|
|
179
|
+
private hoverAppendPad;
|
|
167
180
|
clickAppendElementButton(): Promise<void>;
|
|
168
181
|
clickMarketPlaceButton(): Promise<void>;
|
|
169
182
|
clickPublicHolidayConnectorOption(): Promise<void>;
|
|
@@ -41,6 +41,7 @@ class ModelerCreatePage {
|
|
|
41
41
|
firstPlacedElement;
|
|
42
42
|
secondPlacedElement;
|
|
43
43
|
appendElementButton;
|
|
44
|
+
appendIndicator;
|
|
44
45
|
payloadInput;
|
|
45
46
|
marketPlaceButton;
|
|
46
47
|
publicHolidayConnectorOption;
|
|
@@ -114,6 +115,12 @@ class ModelerCreatePage {
|
|
|
114
115
|
this.appendElementButton = page
|
|
115
116
|
.locator('[class="djs-create-pad open djs-append-create-pad"]')
|
|
116
117
|
.first();
|
|
118
|
+
// Web Modeler renders a "+" indicator next to every appendable element and
|
|
119
|
+
// marks the selected element's one as `selected`; hovering it opens the
|
|
120
|
+
// append pad.
|
|
121
|
+
this.appendIndicator = page
|
|
122
|
+
.locator('.djs-append-indicator.selected:visible')
|
|
123
|
+
.first();
|
|
117
124
|
this.appendTaskButton = page.getByRole('button', { name: 'Append task' });
|
|
118
125
|
this.changeTypeButton = page.getByRole('button', {
|
|
119
126
|
name: 'Change element',
|
|
@@ -449,7 +456,7 @@ class ModelerCreatePage {
|
|
|
449
456
|
else if (parentElement == 'parallelGateway') {
|
|
450
457
|
await this.clickSecondPlacedGateway();
|
|
451
458
|
}
|
|
452
|
-
await this.
|
|
459
|
+
await this.hoverAppendPad(60000);
|
|
453
460
|
await this.appendEndEventButton.click({ timeout: 120000 });
|
|
454
461
|
}
|
|
455
462
|
}
|
|
@@ -736,16 +743,31 @@ class ModelerCreatePage {
|
|
|
736
743
|
async clickSecondElement() {
|
|
737
744
|
await this.secondElement.click({ timeout: 60000 });
|
|
738
745
|
}
|
|
746
|
+
/**
|
|
747
|
+
* Hovers the append ("+") pad of the current selection, opening it first
|
|
748
|
+
* when it is not already on screen.
|
|
749
|
+
*
|
|
750
|
+
* Since camunda/improved-canvas commit 3e2aa7a ("show append indicator
|
|
751
|
+
* instead of full pad when selection has outgoing flow") the full append pad
|
|
752
|
+
* only auto-opens for elements without an outgoing sequence flow. A selected
|
|
753
|
+
* element that already has one now shows a `.djs-append-indicator` "+"
|
|
754
|
+
* whose `mouseenter` opens the pad — see
|
|
755
|
+
* `lib/bpmn/appendIndicator/AppendIndicator.js` in that repo.
|
|
756
|
+
*/
|
|
757
|
+
async hoverAppendPad(timeout) {
|
|
758
|
+
if (!(await this.appendElementButton.isVisible())) {
|
|
759
|
+
await this.appendIndicator.hover({ timeout });
|
|
760
|
+
}
|
|
761
|
+
await this.appendElementButton.hover({ timeout, force: true });
|
|
762
|
+
}
|
|
739
763
|
async clickAppendElementButton() {
|
|
740
764
|
try {
|
|
741
|
-
|
|
742
|
-
await
|
|
743
|
-
await this.appendElementButton.hover({ timeout: 60000, force: true });
|
|
765
|
+
await (0, sleep_1.sleep)(10000);
|
|
766
|
+
await this.hoverAppendPad(60000);
|
|
744
767
|
}
|
|
745
768
|
catch (error) {
|
|
746
|
-
|
|
747
|
-
await
|
|
748
|
-
await this.appendElementButton.hover({ timeout: 90000, force: true });
|
|
769
|
+
await (0, sleep_1.sleep)(10000);
|
|
770
|
+
await this.hoverAppendPad(90000);
|
|
749
771
|
}
|
|
750
772
|
}
|
|
751
773
|
async clickMarketPlaceButton() {
|
|
@@ -972,7 +994,7 @@ class ModelerCreatePage {
|
|
|
972
994
|
await this.page.reload();
|
|
973
995
|
await (0, sleep_1.sleep)(10000);
|
|
974
996
|
await this.clickFirstPlacedElement();
|
|
975
|
-
await this.
|
|
997
|
+
await this.hoverAppendPad(60000);
|
|
976
998
|
}
|
|
977
999
|
await this.clickAppendGatewayButton();
|
|
978
1000
|
await this.clickChangeTypeButton();
|
|
@@ -181,10 +181,7 @@ _8_10_1.test.describe('HTO User Flow Tests', () => {
|
|
|
181
181
|
await (0, expectTextWithPagination_1.expectTextWithPagination)(page, processName + '2');
|
|
182
182
|
});
|
|
183
183
|
});
|
|
184
|
-
|
|
185
|
-
// https://github.com/camunda/c8-cross-component-e2e-tests/pull/3144
|
|
186
|
-
// Re-enable in the same change that lands #3144.
|
|
187
|
-
_8_10_1.test.skip('Zeebe User Task With Priority', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, taskPanelPage, taskDetailsPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
|
|
184
|
+
(0, _8_10_1.test)('Zeebe User Task With Priority', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, taskPanelPage, taskDetailsPage, operateHomePage, operateProcessesPage, operateProcessInstancePage, }) => {
|
|
188
185
|
const randomName = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
189
186
|
const processName = 'Zeebe_User_Task_Process_With_Priority' + randomName;
|
|
190
187
|
const taskName = 'priorityTest' + randomName;
|
|
@@ -32,7 +32,13 @@ const assertUnauthorizedResponseBody = async (response) => {
|
|
|
32
32
|
}
|
|
33
33
|
expectUnauthorizedErrorBody(body);
|
|
34
34
|
};
|
|
35
|
-
|
|
35
|
+
// Optimize's report endpoint is fronted by the SaaS gateway, which
|
|
36
|
+
// intermittently answers a bare 520 for a request that succeeds on the next
|
|
37
|
+
// attempt. Every other creation helper this hook calls (createCollection,
|
|
38
|
+
// createDashboard) already goes through retryOnTransientApiError; these two
|
|
39
|
+
// spec-local ones did not, so a single gateway blip failed the whole
|
|
40
|
+
// beforeAll and with it every test the worker had picked up.
|
|
41
|
+
const createNumberReport = async (request, options) => (0, apiHelpers_1.retryOnTransientApiError)(async () => {
|
|
36
42
|
const response = await request.post(`${options.baseUrl}/api/report/process/single`, {
|
|
37
43
|
headers: {
|
|
38
44
|
Cookie: options.optimizeCookie,
|
|
@@ -63,8 +69,9 @@ const createNumberReport = async (request, options) => {
|
|
|
63
69
|
const body = await response.json();
|
|
64
70
|
(0, test_1.expect)(body).toHaveProperty('id');
|
|
65
71
|
return body.id;
|
|
66
|
-
};
|
|
67
|
-
|
|
72
|
+
}, 'createNumberReport');
|
|
73
|
+
// Same transient-520 guard as createNumberReport above.
|
|
74
|
+
const createRawDataReport = async (request, options) => (0, apiHelpers_1.retryOnTransientApiError)(async () => {
|
|
68
75
|
const response = await request.post(`${options.baseUrl}/api/report/process/single`, {
|
|
69
76
|
headers: {
|
|
70
77
|
Cookie: options.optimizeCookie,
|
|
@@ -95,7 +102,7 @@ const createRawDataReport = async (request, options) => {
|
|
|
95
102
|
const body = await response.json();
|
|
96
103
|
(0, test_1.expect)(body).toHaveProperty('id');
|
|
97
104
|
return body.id;
|
|
98
|
-
};
|
|
105
|
+
}, 'createRawDataReport');
|
|
99
106
|
_8_10_1.test.describe('API Optimize Sharing, Alerts & Export Tests @optimize-sharing-alerts-export-api @8.10', () => {
|
|
100
107
|
let optimizeCookie;
|
|
101
108
|
let csrfToken;
|
|
@@ -27,10 +27,7 @@ _8_10_1.test.describe('Smoke Tests', () => {
|
|
|
27
27
|
await (0, _setup_1.captureScreenshot)(page, testInfo);
|
|
28
28
|
await (0, _setup_1.captureFailureVideo)(page, testInfo);
|
|
29
29
|
});
|
|
30
|
-
|
|
31
|
-
// https://github.com/camunda/c8-cross-component-e2e-tests/pull/3144
|
|
32
|
-
// Re-enable in the same change that lands #3144.
|
|
33
|
-
_8_10_1.test.skip('Most Common Flow User Flow With All Apps', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
30
|
+
(0, _8_10_1.test)('Most Common Flow User Flow With All Apps', async ({ page, homePage, modelerHomePage, appsPage, modelerCreatePage, formJsPage, }) => {
|
|
34
31
|
_8_10_1.test.slow();
|
|
35
32
|
const randomString = await (0, _setup_1.generateRandomStringAsync)(3);
|
|
36
33
|
const formName = 'New form' + randomString;
|
|
@@ -7,6 +7,7 @@ export declare function expectUnauthorizedErrorBody(body: unknown): void;
|
|
|
7
7
|
export declare function assertUnauthorizedResponseBody(response: APIResponse): Promise<void>;
|
|
8
8
|
export declare function sendRequestAndAssertResponse(request: APIRequestContext, url: string, requestBody?: string | Buffer | Serializable, maxRetries?: number): Promise<void>;
|
|
9
9
|
export declare function retryOn500(fn: () => Promise<APIResponse>, maxAttempts?: number, delayMs?: number): Promise<APIResponse>;
|
|
10
|
+
export declare function retryOnTransientApiError<T>(fn: () => Promise<T>, label: string, maxAttempts?: number, delayMs?: number): Promise<T>;
|
|
10
11
|
export declare function buildZeebeApiUrl(resourcePath: string, environmentOverride?: 'saas' | 'sm', clusterType?: string): string;
|
|
11
12
|
export declare function authAPI(environment: 'saas'): Promise<string>;
|
|
12
13
|
export declare function authAPI(environment: 'sm'): Promise<string>;
|
package/dist/utils/apiHelpers.js
CHANGED
|
@@ -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.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.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");
|
|
@@ -97,7 +97,14 @@ async function retryOnTransientApiError(fn, label, maxAttempts = 3, delayMs = 30
|
|
|
97
97
|
return await fn();
|
|
98
98
|
}
|
|
99
99
|
catch (error) {
|
|
100
|
-
const
|
|
100
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
101
|
+
// assertResponseStatus reports the status through expect(), which
|
|
102
|
+
// colourises it: the message is literally `Received: <SGR>520<SGR>`. The
|
|
103
|
+
// escape sits between `Received:` and the digits, so the 5xx branch below
|
|
104
|
+
// never matched and a genuine gateway blip (Optimize answering 520) was
|
|
105
|
+
// surfaced as a hard failure. Strip the escapes before matching.
|
|
106
|
+
// eslint-disable-next-line no-control-regex
|
|
107
|
+
const message = raw.replace(/\u001b\[\d+m/g, '');
|
|
101
108
|
const isTransient = /Request timed out/i.test(message) ||
|
|
102
109
|
/Received:\s*5\d{2}/.test(message) ||
|
|
103
110
|
/socket hang up/i.test(message) ||
|
|
@@ -114,6 +121,7 @@ async function retryOnTransientApiError(fn, label, maxAttempts = 3, delayMs = 30
|
|
|
114
121
|
}
|
|
115
122
|
throw new Error('unreachable');
|
|
116
123
|
}
|
|
124
|
+
exports.retryOnTransientApiError = retryOnTransientApiError;
|
|
117
125
|
// ---- Cluster Credentials Helper ----
|
|
118
126
|
function getClusterCredentials(clusterType) {
|
|
119
127
|
if (!clusterType) {
|
package/dist/utils/constants.js
CHANGED
|
@@ -17,10 +17,14 @@ exports.deletionAssertionOptions = {
|
|
|
17
17
|
// Longest options for audit-log assertions: entries land in secondary storage
|
|
18
18
|
// only after the audit config propagates to the exporters, which is markedly
|
|
19
19
|
// slower on freshly-provisioned SaaS clusters. 90s occasionally lapsed before
|
|
20
|
-
// the CLIENT-actor PROCESS_INSTANCE CREATE entry surfaced,
|
|
20
|
+
// the CLIENT-actor PROCESS_INSTANCE CREATE entry surfaced, then 180s did too
|
|
21
|
+
// (every audit test in the nightly timed out on the same fresh org, including
|
|
22
|
+
// the REST-triggered one, so nothing about the entry itself was wrong — the
|
|
23
|
+
// pipeline simply had not started exporting yet). Poll for 360s, which still
|
|
24
|
+
// leaves headroom inside the 12-minute test timeout after the ~60s beforeAll.
|
|
21
25
|
exports.auditLogAssertionOptions = {
|
|
22
26
|
intervals: [5000, 10000, 15000, 20000, 30000],
|
|
23
|
-
timeout:
|
|
27
|
+
timeout: 360000,
|
|
24
28
|
};
|
|
25
29
|
exports.TIMEOUT = {
|
|
26
30
|
short: 15000,
|