@digital-ai/devops-page-object-deploy 0.0.9 → 0.0.11
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/CHANGELOG.md +12 -0
- package/dist/main.js +277 -0
- package/dist/main.js.map +1 -1
- package/dist/module.js +277 -0
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +36 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @digital-ai/devops-page-object-deploy
|
|
2
2
|
|
|
3
|
+
## 0.0.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7a22243: Check Connection for Gitops CI
|
|
8
|
+
|
|
9
|
+
## 0.0.10
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 0c70fa6: S-126088-New Gitops-Page Objects
|
|
14
|
+
|
|
3
15
|
## 0.0.9
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/main.js
CHANGED
|
@@ -1143,6 +1143,248 @@ class $408106958eb335da$export$1533b625ec0c75e2 extends (0, $84f8d1abd29d48fd$ex
|
|
|
1143
1143
|
|
|
1144
1144
|
|
|
1145
1145
|
|
|
1146
|
+
class $179e7dbfee839d39$export$95a11cbd2815051e extends (0, $84f8d1abd29d48fd$export$cb21416f3c2fd176) {
|
|
1147
|
+
constructor(page){
|
|
1148
|
+
super(page);
|
|
1149
|
+
}
|
|
1150
|
+
/* Helps to navigate to the Gitops Configuration page */ async navigateToGitopsConfigurationPage() {
|
|
1151
|
+
await this.openRootContextMenu('Configuration');
|
|
1152
|
+
await this.page.getByRole('link', {
|
|
1153
|
+
name: 'New'
|
|
1154
|
+
}).click();
|
|
1155
|
+
await this.page.locator('a[title="git"]').click();
|
|
1156
|
+
await this.page.getByRole('link', {
|
|
1157
|
+
name: 'GitSource'
|
|
1158
|
+
}).click();
|
|
1159
|
+
await this.ensureExplorerTreeReady();
|
|
1160
|
+
}
|
|
1161
|
+
async openNewgitops() {
|
|
1162
|
+
await this.closeModalIfPresent();
|
|
1163
|
+
await this.ensureExplorerTreeReady();
|
|
1164
|
+
const infrastructureRoot = this.page.locator('span[data-id="Configuration"]');
|
|
1165
|
+
await infrastructureRoot.scrollIntoViewIfNeeded();
|
|
1166
|
+
await infrastructureRoot.click();
|
|
1167
|
+
const contextMenu = this.page.locator('i.context-menu-button[data-id="Configuration"]');
|
|
1168
|
+
await contextMenu.scrollIntoViewIfNeeded();
|
|
1169
|
+
await contextMenu.click({
|
|
1170
|
+
force: true
|
|
1171
|
+
});
|
|
1172
|
+
await this.page.getByRole('link', {
|
|
1173
|
+
name: 'New'
|
|
1174
|
+
}).click();
|
|
1175
|
+
await this.page.locator('a[title="git"]').click();
|
|
1176
|
+
await this.page.getByRole('link', {
|
|
1177
|
+
name: 'GitSource'
|
|
1178
|
+
}).click();
|
|
1179
|
+
}
|
|
1180
|
+
async openConfigurationNewgit() {
|
|
1181
|
+
await this.openNewgitops();
|
|
1182
|
+
}
|
|
1183
|
+
/* Helps to create a gitops ci*/ async createGitopsCI(ciName, gitData) {
|
|
1184
|
+
await this.page.locator('input[name="name"]').fill(ciName);
|
|
1185
|
+
await this.page.locator('input[name="username"]').fill(gitData[0]);
|
|
1186
|
+
await this.page.locator('input[name="password"]').fill(gitData[1]);
|
|
1187
|
+
await this.page.locator('input[name="url"]').fill(gitData[2]);
|
|
1188
|
+
await this.page.getByRole('button', {
|
|
1189
|
+
name: /^Save and close$/i
|
|
1190
|
+
}).click();
|
|
1191
|
+
await this.handleSaveToastOrAlreadyExists();
|
|
1192
|
+
}
|
|
1193
|
+
/**
|
|
1194
|
+
* Opens New -> git -> GitDirectory under the provided GitSource node.
|
|
1195
|
+
* @param gitSourceDataId The full tree data-id, e.g. "Configuration/MyGitSource"
|
|
1196
|
+
*/ async openNewGitDirectoryUnderGitSource(gitSourceDataId) {
|
|
1197
|
+
const configurationToggle = this.page.locator('div[data-id="Configuration"] .infinite-tree-node > a');
|
|
1198
|
+
const gitSourceNode = this.page.locator(`span[data-id="${gitSourceDataId}"]`);
|
|
1199
|
+
for(let attempt = 0; attempt < 3; attempt += 1){
|
|
1200
|
+
if (await gitSourceNode.count() > 0 && await gitSourceNode.isVisible()) break;
|
|
1201
|
+
await configurationToggle.click();
|
|
1202
|
+
await this.page.waitForTimeout(500);
|
|
1203
|
+
}
|
|
1204
|
+
await gitSourceNode.scrollIntoViewIfNeeded();
|
|
1205
|
+
await gitSourceNode.hover();
|
|
1206
|
+
const contextMenu = this.page.locator(`i.context-menu-button[data-id="${gitSourceDataId}"]`);
|
|
1207
|
+
await contextMenu.waitFor({
|
|
1208
|
+
state: 'visible',
|
|
1209
|
+
timeout: 5000
|
|
1210
|
+
});
|
|
1211
|
+
await contextMenu.click({
|
|
1212
|
+
force: true
|
|
1213
|
+
});
|
|
1214
|
+
await this.page.getByRole('link', {
|
|
1215
|
+
name: /^New$/i
|
|
1216
|
+
}).click();
|
|
1217
|
+
await this.page.getByRole('link', {
|
|
1218
|
+
name: /^git$/i
|
|
1219
|
+
}).click();
|
|
1220
|
+
await this.page.getByRole('link', {
|
|
1221
|
+
name: /^GitDirectory$/i
|
|
1222
|
+
}).click();
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Runs the "Check connection" control task on the given GitSource node once.
|
|
1226
|
+
* @param gitSourceDataId The full tree data-id, e.g. "Configuration/MyGitSource"
|
|
1227
|
+
*/ async runCheckConnection(gitSourceDataId) {
|
|
1228
|
+
const configurationToggle = this.page.locator('div[data-id="Configuration"] .infinite-tree-node > a');
|
|
1229
|
+
const gitSourceNode = this.page.locator(`span[data-id="${gitSourceDataId}"]`);
|
|
1230
|
+
// Ensure the GitSource node is visible in the tree before opening context menu.
|
|
1231
|
+
for(let attempt = 0; attempt < 3; attempt += 1){
|
|
1232
|
+
if (await gitSourceNode.count() > 0 && await gitSourceNode.isVisible()) break;
|
|
1233
|
+
await configurationToggle.click();
|
|
1234
|
+
await this.page.waitForTimeout(500);
|
|
1235
|
+
}
|
|
1236
|
+
await gitSourceNode.waitFor({
|
|
1237
|
+
state: 'visible',
|
|
1238
|
+
timeout: 5000
|
|
1239
|
+
});
|
|
1240
|
+
await gitSourceNode.scrollIntoViewIfNeeded();
|
|
1241
|
+
await gitSourceNode.hover();
|
|
1242
|
+
const ctxBtn = this.page.locator(`i.context-menu-button[data-id="${gitSourceDataId}"]`);
|
|
1243
|
+
await ctxBtn.waitFor({
|
|
1244
|
+
state: 'visible',
|
|
1245
|
+
timeout: 5000
|
|
1246
|
+
});
|
|
1247
|
+
await ctxBtn.click({
|
|
1248
|
+
force: true
|
|
1249
|
+
});
|
|
1250
|
+
await this.page.getByRole('link', {
|
|
1251
|
+
name: /check connection/i
|
|
1252
|
+
}).click();
|
|
1253
|
+
await this.page.locator('.xl-react-widget-modal-dialog button.deploy.xl-primary, button.xl-primary:has-text("Execute")').first().waitFor({
|
|
1254
|
+
state: 'visible',
|
|
1255
|
+
timeout: 10000
|
|
1256
|
+
});
|
|
1257
|
+
await this.page.locator('.xl-react-widget-modal-dialog button.deploy.xl-primary, button.xl-primary:has-text("Execute")').first().click();
|
|
1258
|
+
// Wait for DONE status
|
|
1259
|
+
const doneLabel = this.page.locator('span.label', {
|
|
1260
|
+
hasText: 'DONE'
|
|
1261
|
+
}).first();
|
|
1262
|
+
await doneLabel.waitFor({
|
|
1263
|
+
state: 'visible',
|
|
1264
|
+
timeout: 45000
|
|
1265
|
+
});
|
|
1266
|
+
// Capture task ID using the same source as deployment flows.
|
|
1267
|
+
const taskIdLocator = this.page.locator('div.task-id').first();
|
|
1268
|
+
await (0, $1UEKj$playwrighttest.expect)(taskIdLocator).toBeVisible({
|
|
1269
|
+
timeout: 60000
|
|
1270
|
+
});
|
|
1271
|
+
await (0, $1UEKj$playwrighttest.expect)(taskIdLocator).not.toHaveText('', {
|
|
1272
|
+
timeout: 60000
|
|
1273
|
+
});
|
|
1274
|
+
const capturedTaskId = (await taskIdLocator.textContent() ?? '').trim();
|
|
1275
|
+
if (!capturedTaskId) throw new Error(`Unable to capture check connection task ID for ${gitSourceDataId}.`);
|
|
1276
|
+
this.taskId = capturedTaskId;
|
|
1277
|
+
this.executedText = 'DONE';
|
|
1278
|
+
this.targetCi = gitSourceDataId;
|
|
1279
|
+
// Finish
|
|
1280
|
+
const finishButton = this.page.locator('button.finish.xl-primary, button:has-text("Finish")').first();
|
|
1281
|
+
if (await finishButton.isVisible()) await finishButton.click();
|
|
1282
|
+
// Wait for modal/plan to close
|
|
1283
|
+
const modal = this.page.locator('div.xl-react-widget-modal-dialog.in');
|
|
1284
|
+
if (await modal.count() > 0) await modal.first().waitFor({
|
|
1285
|
+
state: 'hidden',
|
|
1286
|
+
timeout: 15000
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* Runs the "Check connection" control task and expects it to fail with invalid credentials.
|
|
1291
|
+
* @param gitSourceDataId The full tree data-id, e.g. "Configuration/MyGitSource"
|
|
1292
|
+
*/ async runCheckConnectionExpectFailure(gitSourceDataId) {
|
|
1293
|
+
const configurationToggle = this.page.locator('div[data-id="Configuration"] .infinite-tree-node > a');
|
|
1294
|
+
const gitSourceNode = this.page.locator(`span[data-id="${gitSourceDataId}"]`);
|
|
1295
|
+
// Ensure the GitSource node is visible in the tree before opening context menu.
|
|
1296
|
+
for(let attempt = 0; attempt < 3; attempt += 1){
|
|
1297
|
+
if (await gitSourceNode.count() > 0 && await gitSourceNode.isVisible()) break;
|
|
1298
|
+
await configurationToggle.click();
|
|
1299
|
+
await this.page.waitForTimeout(500);
|
|
1300
|
+
}
|
|
1301
|
+
await gitSourceNode.scrollIntoViewIfNeeded();
|
|
1302
|
+
await gitSourceNode.hover();
|
|
1303
|
+
const ctxBtn = this.page.locator(`i.context-menu-button[data-id="${gitSourceDataId}"]`);
|
|
1304
|
+
await ctxBtn.waitFor({
|
|
1305
|
+
state: 'visible',
|
|
1306
|
+
timeout: 5000
|
|
1307
|
+
});
|
|
1308
|
+
await ctxBtn.click({
|
|
1309
|
+
force: true
|
|
1310
|
+
});
|
|
1311
|
+
await this.page.getByRole('link', {
|
|
1312
|
+
name: /check connection/i
|
|
1313
|
+
}).click();
|
|
1314
|
+
// Click Execute button
|
|
1315
|
+
await this.page.locator('.xl-react-widget-modal-dialog button.deploy.xl-primary, button.xl-primary:has-text("Execute")').first().waitFor({
|
|
1316
|
+
state: 'visible',
|
|
1317
|
+
timeout: 10000
|
|
1318
|
+
});
|
|
1319
|
+
await this.page.locator('.xl-react-widget-modal-dialog button.deploy.xl-primary, button.xl-primary:has-text("Execute")').first().click();
|
|
1320
|
+
// Wait for FAILED status (instead of EXECUTED)
|
|
1321
|
+
const failedLabel = this.page.locator('span.label', {
|
|
1322
|
+
hasText: 'FAILED'
|
|
1323
|
+
}).first();
|
|
1324
|
+
await failedLabel.waitFor({
|
|
1325
|
+
state: 'visible',
|
|
1326
|
+
timeout: 30000
|
|
1327
|
+
});
|
|
1328
|
+
// Finish
|
|
1329
|
+
const finishButton = this.page.locator('button.finish.xl-primary, button:has-text("Finish")').first();
|
|
1330
|
+
if (await finishButton.isVisible()) await finishButton.click();
|
|
1331
|
+
// Wait for modal/plan to close
|
|
1332
|
+
const modal = this.page.locator('div.xl-react-widget-modal-dialog.in');
|
|
1333
|
+
if (await modal.count() > 0) await modal.first().waitFor({
|
|
1334
|
+
state: 'hidden',
|
|
1335
|
+
timeout: 15000
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Verifies the captured Check Connection task in Reports -> Control tasks.
|
|
1340
|
+
*/ async verifyCheckConnectionTaskInReports() {
|
|
1341
|
+
if (!this.taskId) throw new Error('Check connection task ID is empty. Run check connection before verifying reports.');
|
|
1342
|
+
await this.page.locator('p.MuiTypography-root', {
|
|
1343
|
+
hasText: 'Reports'
|
|
1344
|
+
}).click();
|
|
1345
|
+
const controlTasksTab = this.page.locator('.app-root .dot-sidebar .dot-list p').filter({
|
|
1346
|
+
hasText: 'Control tasks'
|
|
1347
|
+
}).first();
|
|
1348
|
+
await controlTasksTab.scrollIntoViewIfNeeded();
|
|
1349
|
+
await controlTasksTab.click();
|
|
1350
|
+
const pane = this.page.locator('#pane-ControlTasksTab');
|
|
1351
|
+
await pane.waitFor({
|
|
1352
|
+
state: 'visible',
|
|
1353
|
+
timeout: 20000
|
|
1354
|
+
});
|
|
1355
|
+
const showFilters = pane.getByRole('button', {
|
|
1356
|
+
name: 'Show filters'
|
|
1357
|
+
});
|
|
1358
|
+
if (await showFilters.isVisible()) await showFilters.click({
|
|
1359
|
+
force: true
|
|
1360
|
+
});
|
|
1361
|
+
const taskIdFilter = pane.locator('.control-task-id input[placeholder="Search"]');
|
|
1362
|
+
await taskIdFilter.fill(this.taskId);
|
|
1363
|
+
const tableBody = pane.locator('table.table-striped tbody');
|
|
1364
|
+
const row = tableBody.locator('tr').filter({
|
|
1365
|
+
hasText: this.taskId
|
|
1366
|
+
}).first();
|
|
1367
|
+
for(let attempt = 0; attempt < 3; attempt += 1){
|
|
1368
|
+
if (await row.count() > 0 && await row.isVisible()) break;
|
|
1369
|
+
const refreshButton = pane.getByRole('button', {
|
|
1370
|
+
name: 'Refresh'
|
|
1371
|
+
});
|
|
1372
|
+
if (await refreshButton.isVisible()) await refreshButton.click();
|
|
1373
|
+
await this.page.waitForTimeout(1500);
|
|
1374
|
+
}
|
|
1375
|
+
await (0, $1UEKj$playwrighttest.expect)(row).toBeVisible({
|
|
1376
|
+
timeout: 30000
|
|
1377
|
+
});
|
|
1378
|
+
await (0, $1UEKj$playwrighttest.expect)(row).toContainText(this.taskId);
|
|
1379
|
+
await (0, $1UEKj$playwrighttest.expect)(row).toContainText(/check connection/i);
|
|
1380
|
+
await (0, $1UEKj$playwrighttest.expect)(row).toContainText(new RegExp(this.executedText, 'i'));
|
|
1381
|
+
await (0, $1UEKj$playwrighttest.expect)(row).toContainText(this.targetCi);
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
|
|
1386
|
+
|
|
1387
|
+
|
|
1146
1388
|
class $b2f725a937c99e2d$export$b8a443164510a1b4 extends (0, $ae23b16684112d0b$export$2b65d1d97338f32b) {
|
|
1147
1389
|
async openTab(tabLabel, paneId) {
|
|
1148
1390
|
const tab = this.page.locator('.app-root .dot-sidebar .dot-list p').filter({
|
|
@@ -2536,6 +2778,39 @@ class $7735c50a40aa728e$export$ecd8b3e50e92d781 extends (0, $84f8d1abd29d48fd$ex
|
|
|
2536
2778
|
}
|
|
2537
2779
|
|
|
2538
2780
|
|
|
2781
|
+
|
|
2782
|
+
class $51cef27488199b02$export$170f2cb42585788e extends (0, $84f8d1abd29d48fd$export$cb21416f3c2fd176) {
|
|
2783
|
+
/* Navigates to the Configuration Edit Permissions page via the tree context menu */ async navigateToPage() {
|
|
2784
|
+
await this.openRootContextMenu('Configuration');
|
|
2785
|
+
await this.page.getByRole('link', {
|
|
2786
|
+
name: 'Edit Permissions'
|
|
2787
|
+
}).click();
|
|
2788
|
+
}
|
|
2789
|
+
async navigateToConfigurationEditPermissionsPage() {
|
|
2790
|
+
await this.navigateToPage();
|
|
2791
|
+
}
|
|
2792
|
+
/* Gives the permissions to a role */ async givePermissionsToRole(roleName) {
|
|
2793
|
+
const filter = this.page.getByPlaceholder('Filter by roles').first();
|
|
2794
|
+
await filter.waitFor({
|
|
2795
|
+
state: 'visible'
|
|
2796
|
+
});
|
|
2797
|
+
await filter.scrollIntoViewIfNeeded();
|
|
2798
|
+
await filter.fill(roleName);
|
|
2799
|
+
const roleRow = this.page.locator('table.table-striped tbody tr').first();
|
|
2800
|
+
const checkboxes = roleRow.locator('input[type="checkbox"]');
|
|
2801
|
+
const count = await checkboxes.count();
|
|
2802
|
+
for(let i = 0; i < count; i += 1){
|
|
2803
|
+
const checkbox = checkboxes.nth(i);
|
|
2804
|
+
if (!await checkbox.isChecked()) await checkbox.check();
|
|
2805
|
+
}
|
|
2806
|
+
await this.page.getByRole('button', {
|
|
2807
|
+
name: 'Save and close'
|
|
2808
|
+
}).click();
|
|
2809
|
+
await this.handleSaveToastOrAlreadyExists();
|
|
2810
|
+
}
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
|
|
2539
2814
|
class $28788a34e6bbbe3d$export$b8a61e5c71402559 extends (0, $84f8d1abd29d48fd$export$cb21416f3c2fd176) {
|
|
2540
2815
|
constructor(page){
|
|
2541
2816
|
super(page);
|
|
@@ -2551,6 +2826,8 @@ class $28788a34e6bbbe3d$export$b8a61e5c71402559 extends (0, $84f8d1abd29d48fd$ex
|
|
|
2551
2826
|
this.infrastructureEditPermissionsPage = new (0, $9204952bd68f68e5$export$e37b272c81a10693)(page);
|
|
2552
2827
|
this.environmentEditPermissionsPage = new (0, $05857e702fc1e333$export$c919546f4bf88f35)(page);
|
|
2553
2828
|
this.applicationEditPermissionsPage = new (0, $7735c50a40aa728e$export$ecd8b3e50e92d781)(page);
|
|
2829
|
+
this.configurationEditPermissionsPage = new (0, $51cef27488199b02$export$170f2cb42585788e)(page);
|
|
2830
|
+
this.gitopsConfigurationPage = new (0, $179e7dbfee839d39$export$95a11cbd2815051e)(page);
|
|
2554
2831
|
}
|
|
2555
2832
|
async navigateToHomePage() {
|
|
2556
2833
|
await this.page.goto('/home');
|