@camunda/e2e-test-suite 0.0.1443 → 0.0.1444
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/.github/c8_versions.json +1 -0
- package/README.md +2 -0
- package/dist/fixtures/SM-8.11.d.ts +77 -0
- package/dist/fixtures/SM-8.11.js +176 -0
- package/dist/pages/SM-8.11/Authorization.d.ts +39 -0
- package/dist/pages/SM-8.11/Authorization.js +349 -0
- package/dist/pages/SM-8.11/ClusterDetailsPage.d.ts +8 -0
- package/dist/pages/SM-8.11/ClusterDetailsPage.js +65 -0
- package/dist/pages/SM-8.11/ClusterPage.d.ts +11 -0
- package/dist/pages/SM-8.11/ClusterPage.js +37 -0
- package/dist/pages/SM-8.11/ConnectorMarketplacePage.d.ts +27 -0
- package/dist/pages/SM-8.11/ConnectorMarketplacePage.js +187 -0
- package/dist/pages/SM-8.11/ConnectorSettingsPage.d.ts +41 -0
- package/dist/pages/SM-8.11/ConnectorSettingsPage.js +153 -0
- package/dist/pages/SM-8.11/ConnectorTemplatePage.d.ts +11 -0
- package/dist/pages/SM-8.11/ConnectorTemplatePage.js +34 -0
- package/dist/pages/SM-8.11/FormJsPage.d.ts +33 -0
- package/dist/pages/SM-8.11/FormJsPage.js +109 -0
- package/dist/pages/SM-8.11/HomePage.d.ts +20 -0
- package/dist/pages/SM-8.11/HomePage.js +49 -0
- package/dist/pages/SM-8.11/IdentityTenantPage.d.ts +53 -0
- package/dist/pages/SM-8.11/IdentityTenantPage.js +264 -0
- package/dist/pages/SM-8.11/IdentityUsersPage.d.ts +92 -0
- package/dist/pages/SM-8.11/IdentityUsersPage.js +485 -0
- package/dist/pages/SM-8.11/KeycloakAdminPage.d.ts +17 -0
- package/dist/pages/SM-8.11/KeycloakAdminPage.js +78 -0
- package/dist/pages/SM-8.11/KeycloakLoginPage.d.ts +12 -0
- package/dist/pages/SM-8.11/KeycloakLoginPage.js +32 -0
- package/dist/pages/SM-8.11/KeycloakUtils.d.ts +17 -0
- package/dist/pages/SM-8.11/KeycloakUtils.js +94 -0
- package/dist/pages/SM-8.11/LoginPage.d.ts +21 -0
- package/dist/pages/SM-8.11/LoginPage.js +112 -0
- package/dist/pages/SM-8.11/ManagementIdentityPage.d.ts +44 -0
- package/dist/pages/SM-8.11/ManagementIdentityPage.js +176 -0
- package/dist/pages/SM-8.11/ModelerCreatePage.d.ts +238 -0
- package/dist/pages/SM-8.11/ModelerCreatePage.js +1950 -0
- package/dist/pages/SM-8.11/ModelerHomePage.d.ts +97 -0
- package/dist/pages/SM-8.11/ModelerHomePage.js +956 -0
- package/dist/pages/SM-8.11/NavigationPage.d.ts +58 -0
- package/dist/pages/SM-8.11/NavigationPage.js +389 -0
- package/dist/pages/SM-8.11/OCIdentityAuthorizationsPage.d.ts +10 -0
- package/dist/pages/SM-8.11/OCIdentityAuthorizationsPage.js +22 -0
- package/dist/pages/SM-8.11/OCIdentityClusterVariablesPage.d.ts +22 -0
- package/dist/pages/SM-8.11/OCIdentityClusterVariablesPage.js +120 -0
- package/dist/pages/SM-8.11/OCIdentityGroupsPage.d.ts +39 -0
- package/dist/pages/SM-8.11/OCIdentityGroupsPage.js +154 -0
- package/dist/pages/SM-8.11/OCIdentityHomePage.d.ts +23 -0
- package/dist/pages/SM-8.11/OCIdentityHomePage.js +115 -0
- package/dist/pages/SM-8.11/OCIdentityMappingRulesPage.d.ts +23 -0
- package/dist/pages/SM-8.11/OCIdentityMappingRulesPage.js +116 -0
- package/dist/pages/SM-8.11/OCIdentityRolesPage.d.ts +61 -0
- package/dist/pages/SM-8.11/OCIdentityRolesPage.js +433 -0
- package/dist/pages/SM-8.11/OCTenantPage.d.ts +73 -0
- package/dist/pages/SM-8.11/OCTenantPage.js +399 -0
- package/dist/pages/SM-8.11/OperateHomePage.d.ts +26 -0
- package/dist/pages/SM-8.11/OperateHomePage.js +139 -0
- package/dist/pages/SM-8.11/OperateProcessInstancePage.d.ts +30 -0
- package/dist/pages/SM-8.11/OperateProcessInstancePage.js +276 -0
- package/dist/pages/SM-8.11/OperateProcessesPage.d.ts +38 -0
- package/dist/pages/SM-8.11/OperateProcessesPage.js +383 -0
- package/dist/pages/SM-8.11/OptimizeCollectionsPage.d.ts +17 -0
- package/dist/pages/SM-8.11/OptimizeCollectionsPage.js +62 -0
- package/dist/pages/SM-8.11/OptimizeDashboardPage.d.ts +14 -0
- package/dist/pages/SM-8.11/OptimizeDashboardPage.js +63 -0
- package/dist/pages/SM-8.11/OptimizeHomePage.d.ts +19 -0
- package/dist/pages/SM-8.11/OptimizeHomePage.js +76 -0
- package/dist/pages/SM-8.11/OptimizeReportPage.d.ts +50 -0
- package/dist/pages/SM-8.11/OptimizeReportPage.js +209 -0
- package/dist/pages/SM-8.11/PlayPage.d.ts +47 -0
- package/dist/pages/SM-8.11/PlayPage.js +389 -0
- package/dist/pages/SM-8.11/ProcessApplicationPage.d.ts +35 -0
- package/dist/pages/SM-8.11/ProcessApplicationPage.js +340 -0
- package/dist/pages/SM-8.11/SettingsPage.d.ts +12 -0
- package/dist/pages/SM-8.11/SettingsPage.js +34 -0
- package/dist/pages/SM-8.11/TaskDetailsPage.d.ts +70 -0
- package/dist/pages/SM-8.11/TaskDetailsPage.js +273 -0
- package/dist/pages/SM-8.11/TaskPanelPage.d.ts +29 -0
- package/dist/pages/SM-8.11/TaskPanelPage.js +320 -0
- package/dist/pages/SM-8.11/TaskProcessesPage.d.ts +15 -0
- package/dist/pages/SM-8.11/TaskProcessesPage.js +77 -0
- package/dist/pages/SM-8.11/UtilitiesPage.d.ts +38 -0
- package/dist/pages/SM-8.11/UtilitiesPage.js +573 -0
- package/dist/pages/SM-8.11/optimizeReportUtils.d.ts +6 -0
- package/dist/pages/SM-8.11/optimizeReportUtils.js +77 -0
- package/dist/tests/SM-8.11/cluster-management-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/cluster-management-user-flows.spec.js +48 -0
- package/dist/tests/SM-8.11/cluster-variables.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/cluster-variables.spec.js +226 -0
- package/dist/tests/SM-8.11/connectors-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/connectors-user-flows.spec.js +307 -0
- package/dist/tests/SM-8.11/document-handling-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/document-handling-user-flows.spec.js +174 -0
- package/dist/tests/SM-8.11/hto-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/hto-user-flows.spec.js +410 -0
- package/dist/tests/SM-8.11/hub-web-modeler-smoke.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/hub-web-modeler-smoke.spec.js +24 -0
- package/dist/tests/SM-8.11/identity-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/identity-user-flows.spec.js +220 -0
- package/dist/tests/SM-8.11/license-key-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/license-key-user-flows.spec.js +461 -0
- package/dist/tests/SM-8.11/login.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/login.spec.js +24 -0
- package/dist/tests/SM-8.11/migration-path-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/migration-path-user-flows.spec.js +263 -0
- package/dist/tests/SM-8.11/mt-enabled-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/mt-enabled-user-flows.spec.js +607 -0
- package/dist/tests/SM-8.11/optimize-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/optimize-user-flows.spec.js +505 -0
- package/dist/tests/SM-8.11/play.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/play.spec.js +144 -0
- package/dist/tests/SM-8.11/rba-enabled-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/rba-enabled-user-flows.spec.js +712 -0
- package/dist/tests/SM-8.11/smoke-tests.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/smoke-tests.spec.js +167 -0
- package/dist/tests/SM-8.11/test-setup.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/test-setup.spec.js +24 -0
- package/dist/tests/SM-8.11/topology-orchestration-smoke.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/topology-orchestration-smoke.spec.js +58 -0
- package/dist/tests/SM-8.11/web-modeler-user-flows.spec.d.ts +1 -0
- package/dist/tests/SM-8.11/web-modeler-user-flows.spec.js +223 -0
- package/package.json +1 -1
- package/playwright.config.ts +21 -0
package/.github/c8_versions.json
CHANGED
package/README.md
CHANGED
|
@@ -33,6 +33,8 @@ For the Camunda SM Helm offering, the test suite supports following versions:
|
|
|
33
33
|
- 8.7.X
|
|
34
34
|
- 8.8.X
|
|
35
35
|
- 8.9.X
|
|
36
|
+
- 8.10.X
|
|
37
|
+
- 8.11.X
|
|
36
38
|
|
|
37
39
|
The test suite primarily uses Elasticsearch as the default search engine. However, it also supports OpenSearch, with dedicated workflows explicitly named to indicate OpenSearch as the selected engine.
|
|
38
40
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import AxeBuilder from '@axe-core/playwright';
|
|
2
|
+
import { LoginPage } from '../pages/SM-8.11/LoginPage';
|
|
3
|
+
import { HomePage } from '../pages/SM-8.11/HomePage';
|
|
4
|
+
import { NavigationPage } from '../pages/SM-8.11/NavigationPage';
|
|
5
|
+
import { ModelerHomePage } from '../pages/SM-8.11/ModelerHomePage';
|
|
6
|
+
import { ModelerCreatePage } from '../pages/SM-8.11/ModelerCreatePage';
|
|
7
|
+
import { PlayPage } from '../pages/SM-8.11/PlayPage';
|
|
8
|
+
import { TaskPanelPage } from '../pages/SM-8.11/TaskPanelPage';
|
|
9
|
+
import { TaskDetailsPage } from '../pages/SM-8.11/TaskDetailsPage';
|
|
10
|
+
import { OperateHomePage } from '../pages/SM-8.11/OperateHomePage';
|
|
11
|
+
import { OperateProcessesPage } from '../pages/SM-8.11/OperateProcessesPage';
|
|
12
|
+
import { OperateProcessInstancePage } from '../pages/SM-8.11/OperateProcessInstancePage';
|
|
13
|
+
import { OptimizeCollectionsPage } from '../pages/SM-8.11/OptimizeCollectionsPage';
|
|
14
|
+
import { OptimizeHomePage } from '../pages/SM-8.11/OptimizeHomePage';
|
|
15
|
+
import { FormJsPage } from '../pages/SM-8.11/FormJsPage';
|
|
16
|
+
import { OptimizeReportPage } from '../pages/SM-8.11/OptimizeReportPage';
|
|
17
|
+
import { SettingsPage } from '../pages/SM-8.11/SettingsPage';
|
|
18
|
+
import { ConnectorSettingsPage } from '../pages/SM-8.11/ConnectorSettingsPage';
|
|
19
|
+
import { ConnectorMarketplacePage } from '../pages/SM-8.11/ConnectorMarketplacePage';
|
|
20
|
+
import { OCIdentityHomePage } from '../pages/SM-8.11/OCIdentityHomePage';
|
|
21
|
+
import { OCIdentityMappingRulesPage } from '../pages/SM-8.11/OCIdentityMappingRulesPage';
|
|
22
|
+
import { OCIdentityClusterVariablesPage } from '../pages/SM-8.11/OCIdentityClusterVariablesPage';
|
|
23
|
+
import { OptimizeDashboardPage } from '../pages/SM-8.11/OptimizeDashboardPage';
|
|
24
|
+
import { TaskProcessesPage } from '../pages/SM-8.11/TaskProcessesPage';
|
|
25
|
+
import { IdentityUsersPage } from '../pages/SM-8.11/IdentityUsersPage';
|
|
26
|
+
import { IdentityTenantPage } from '../pages/SM-8.11/IdentityTenantPage';
|
|
27
|
+
import { ClusterDetailsPage } from '../pages/SM-8.11/ClusterDetailsPage';
|
|
28
|
+
import { ClusterPage } from '../pages/SM-8.11/ClusterPage';
|
|
29
|
+
import { ConnectorTemplatePage } from '../pages/SM-8.11/ConnectorTemplatePage';
|
|
30
|
+
import { OCIdentityRolesPage } from '../pages/SM-8.11/OCIdentityRolesPage';
|
|
31
|
+
import { ManagementIdentityPage } from '../pages/SM-8.11/ManagementIdentityPage';
|
|
32
|
+
import { KeycloakAdminPage } from '../pages/SM-8.11/KeycloakAdminPage';
|
|
33
|
+
import { KeycloakLoginPage } from '../pages/SM-8.11/KeycloakLoginPage';
|
|
34
|
+
import { OCIdentityAuthorizationsPage } from '../pages/SM-8.11/OCIdentityAuthorizationsPage';
|
|
35
|
+
import { OCIdentityGroupsPage } from '../pages/SM-8.11/OCIdentityGroupsPage';
|
|
36
|
+
import { OCTenantPage } from '../pages/SM-8.11/OCTenantPage';
|
|
37
|
+
type PlaywrightFixtures = {
|
|
38
|
+
makeAxeBuilder: () => AxeBuilder;
|
|
39
|
+
loginPage: LoginPage;
|
|
40
|
+
homePage: HomePage;
|
|
41
|
+
navigationPage: NavigationPage;
|
|
42
|
+
modelerHomePage: ModelerHomePage;
|
|
43
|
+
modelerCreatePage: ModelerCreatePage;
|
|
44
|
+
playPage: PlayPage;
|
|
45
|
+
taskPanelPage: TaskPanelPage;
|
|
46
|
+
taskDetailsPage: TaskDetailsPage;
|
|
47
|
+
operateHomePage: OperateHomePage;
|
|
48
|
+
operateProcessesPage: OperateProcessesPage;
|
|
49
|
+
optimizeCollectionsPage: OptimizeCollectionsPage;
|
|
50
|
+
operateProcessInstancePage: OperateProcessInstancePage;
|
|
51
|
+
optimizeHomePage: OptimizeHomePage;
|
|
52
|
+
formJsPage: FormJsPage;
|
|
53
|
+
optimizeReportPage: OptimizeReportPage;
|
|
54
|
+
settingsPage: SettingsPage;
|
|
55
|
+
connectorSettingsPage: ConnectorSettingsPage;
|
|
56
|
+
connectorMarketplacePage: ConnectorMarketplacePage;
|
|
57
|
+
ocIdentityHomePage: OCIdentityHomePage;
|
|
58
|
+
ocIdentityMappingRulesPage: OCIdentityMappingRulesPage;
|
|
59
|
+
ocIdentityClusterVariablesPage: OCIdentityClusterVariablesPage;
|
|
60
|
+
optimizeDashboardPage: OptimizeDashboardPage;
|
|
61
|
+
taskProcessesPage: TaskProcessesPage;
|
|
62
|
+
identityUsersPage: IdentityUsersPage;
|
|
63
|
+
managementIdentityTenantPage: IdentityTenantPage;
|
|
64
|
+
ocIdentityRolesPage: OCIdentityRolesPage;
|
|
65
|
+
ocIdentityAuthorizationsPage: OCIdentityAuthorizationsPage;
|
|
66
|
+
managementIdentityPage: ManagementIdentityPage;
|
|
67
|
+
keycloakAdminPage: KeycloakAdminPage;
|
|
68
|
+
keycloakLoginPage: KeycloakLoginPage;
|
|
69
|
+
clusterPage: ClusterPage;
|
|
70
|
+
clusterDetailsPage: ClusterDetailsPage;
|
|
71
|
+
connectorTemplatePage: ConnectorTemplatePage;
|
|
72
|
+
ocIdentityGroupsPage: OCIdentityGroupsPage;
|
|
73
|
+
ocTenantPage: OCTenantPage;
|
|
74
|
+
overrideTrackingScripts: void;
|
|
75
|
+
};
|
|
76
|
+
declare const test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions & PlaywrightFixtures, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
|
|
77
|
+
export { test };
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.test = void 0;
|
|
7
|
+
const test_1 = require("@playwright/test");
|
|
8
|
+
const playwright_1 = __importDefault(require("@axe-core/playwright"));
|
|
9
|
+
const LoginPage_1 = require("../pages/SM-8.11/LoginPage");
|
|
10
|
+
const HomePage_1 = require("../pages/SM-8.11/HomePage");
|
|
11
|
+
const NavigationPage_1 = require("../pages/SM-8.11/NavigationPage");
|
|
12
|
+
const ModelerHomePage_1 = require("../pages/SM-8.11/ModelerHomePage");
|
|
13
|
+
const ModelerCreatePage_1 = require("../pages/SM-8.11/ModelerCreatePage");
|
|
14
|
+
const PlayPage_1 = require("../pages/SM-8.11/PlayPage");
|
|
15
|
+
const TaskPanelPage_1 = require("../pages/SM-8.11/TaskPanelPage");
|
|
16
|
+
const TaskDetailsPage_1 = require("../pages/SM-8.11/TaskDetailsPage");
|
|
17
|
+
const OperateHomePage_1 = require("../pages/SM-8.11/OperateHomePage");
|
|
18
|
+
const OperateProcessesPage_1 = require("../pages/SM-8.11/OperateProcessesPage");
|
|
19
|
+
const OperateProcessInstancePage_1 = require("../pages/SM-8.11/OperateProcessInstancePage");
|
|
20
|
+
const OptimizeCollectionsPage_1 = require("../pages/SM-8.11/OptimizeCollectionsPage");
|
|
21
|
+
const OptimizeHomePage_1 = require("../pages/SM-8.11/OptimizeHomePage");
|
|
22
|
+
const FormJsPage_1 = require("../pages/SM-8.11/FormJsPage");
|
|
23
|
+
const OptimizeReportPage_1 = require("../pages/SM-8.11/OptimizeReportPage");
|
|
24
|
+
const SettingsPage_1 = require("../pages/SM-8.11/SettingsPage");
|
|
25
|
+
const ConnectorSettingsPage_1 = require("../pages/SM-8.11/ConnectorSettingsPage");
|
|
26
|
+
const ConnectorMarketplacePage_1 = require("../pages/SM-8.11/ConnectorMarketplacePage");
|
|
27
|
+
const OCIdentityHomePage_1 = require("../pages/SM-8.11/OCIdentityHomePage");
|
|
28
|
+
const OCIdentityMappingRulesPage_1 = require("../pages/SM-8.11/OCIdentityMappingRulesPage");
|
|
29
|
+
const OCIdentityClusterVariablesPage_1 = require("../pages/SM-8.11/OCIdentityClusterVariablesPage");
|
|
30
|
+
const OptimizeDashboardPage_1 = require("../pages/SM-8.11/OptimizeDashboardPage");
|
|
31
|
+
const TaskProcessesPage_1 = require("../pages/SM-8.11/TaskProcessesPage");
|
|
32
|
+
const IdentityUsersPage_1 = require("../pages/SM-8.11/IdentityUsersPage");
|
|
33
|
+
const IdentityTenantPage_1 = require("../pages/SM-8.11/IdentityTenantPage");
|
|
34
|
+
const ClusterDetailsPage_1 = require("../pages/SM-8.11/ClusterDetailsPage");
|
|
35
|
+
const ClusterPage_1 = require("../pages/SM-8.11/ClusterPage");
|
|
36
|
+
const ConnectorTemplatePage_1 = require("../pages/SM-8.11/ConnectorTemplatePage");
|
|
37
|
+
const OCIdentityRolesPage_1 = require("../pages/SM-8.11/OCIdentityRolesPage");
|
|
38
|
+
const ManagementIdentityPage_1 = require("../pages/SM-8.11/ManagementIdentityPage");
|
|
39
|
+
const KeycloakAdminPage_1 = require("../pages/SM-8.11/KeycloakAdminPage");
|
|
40
|
+
const KeycloakLoginPage_1 = require("../pages/SM-8.11/KeycloakLoginPage");
|
|
41
|
+
const OCIdentityAuthorizationsPage_1 = require("../pages/SM-8.11/OCIdentityAuthorizationsPage");
|
|
42
|
+
const OCIdentityGroupsPage_1 = require("../pages/SM-8.11/OCIdentityGroupsPage");
|
|
43
|
+
const OCTenantPage_1 = require("../pages/SM-8.11/OCTenantPage");
|
|
44
|
+
const test = test_1.test.extend({
|
|
45
|
+
makeAxeBuilder: async ({ page }, use) => {
|
|
46
|
+
const makeAxeBuilder = () => new playwright_1.default({ page }).withTags([
|
|
47
|
+
'best-practice',
|
|
48
|
+
'wcag2a',
|
|
49
|
+
'wcag2aa',
|
|
50
|
+
'cat.semantics',
|
|
51
|
+
'cat.forms',
|
|
52
|
+
]);
|
|
53
|
+
await use(makeAxeBuilder);
|
|
54
|
+
},
|
|
55
|
+
loginPage: async ({ page }, use) => {
|
|
56
|
+
await use(new LoginPage_1.LoginPage(page));
|
|
57
|
+
},
|
|
58
|
+
homePage: async ({ page }, use) => {
|
|
59
|
+
await use(new HomePage_1.HomePage(page));
|
|
60
|
+
},
|
|
61
|
+
navigationPage: async ({ page }, use) => {
|
|
62
|
+
await use(new NavigationPage_1.NavigationPage(page));
|
|
63
|
+
},
|
|
64
|
+
modelerHomePage: async ({ page }, use) => {
|
|
65
|
+
await use(new ModelerHomePage_1.ModelerHomePage(page));
|
|
66
|
+
},
|
|
67
|
+
modelerCreatePage: async ({ page }, use) => {
|
|
68
|
+
await use(new ModelerCreatePage_1.ModelerCreatePage(page));
|
|
69
|
+
},
|
|
70
|
+
playPage: async ({ page }, use) => {
|
|
71
|
+
await use(new PlayPage_1.PlayPage(page));
|
|
72
|
+
},
|
|
73
|
+
taskPanelPage: async ({ page }, use) => {
|
|
74
|
+
await use(new TaskPanelPage_1.TaskPanelPage(page));
|
|
75
|
+
},
|
|
76
|
+
taskDetailsPage: async ({ page }, use) => {
|
|
77
|
+
await use(new TaskDetailsPage_1.TaskDetailsPage(page));
|
|
78
|
+
},
|
|
79
|
+
operateHomePage: async ({ page }, use) => {
|
|
80
|
+
await use(new OperateHomePage_1.OperateHomePage(page));
|
|
81
|
+
},
|
|
82
|
+
operateProcessesPage: async ({ page }, use) => {
|
|
83
|
+
await use(new OperateProcessesPage_1.OperateProcessesPage(page));
|
|
84
|
+
},
|
|
85
|
+
operateProcessInstancePage: async ({ page }, use) => {
|
|
86
|
+
await use(new OperateProcessInstancePage_1.OperateProcessInstancePage(page));
|
|
87
|
+
},
|
|
88
|
+
identityUsersPage: async ({ page }, use) => {
|
|
89
|
+
await use(new IdentityUsersPage_1.IdentityUsersPage(page));
|
|
90
|
+
},
|
|
91
|
+
clusterPage: async ({ page }, use) => {
|
|
92
|
+
await use(new ClusterPage_1.ClusterPage(page));
|
|
93
|
+
},
|
|
94
|
+
clusterDetailsPage: async ({ page }, use) => {
|
|
95
|
+
await use(new ClusterDetailsPage_1.ClusterDetailsPage(page));
|
|
96
|
+
},
|
|
97
|
+
optimizeCollectionsPage: async ({ page }, use) => {
|
|
98
|
+
await use(new OptimizeCollectionsPage_1.OptimizeCollectionsPage(page));
|
|
99
|
+
},
|
|
100
|
+
optimizeHomePage: async ({ page }, use) => {
|
|
101
|
+
await use(new OptimizeHomePage_1.OptimizeHomePage(page));
|
|
102
|
+
},
|
|
103
|
+
formJsPage: async ({ page }, use) => {
|
|
104
|
+
await use(new FormJsPage_1.FormJsPage(page));
|
|
105
|
+
},
|
|
106
|
+
optimizeReportPage: async ({ page }, use) => {
|
|
107
|
+
await use(new OptimizeReportPage_1.OptimizeReportPage(page));
|
|
108
|
+
},
|
|
109
|
+
settingsPage: async ({ page }, use) => {
|
|
110
|
+
await use(new SettingsPage_1.SettingsPage(page));
|
|
111
|
+
},
|
|
112
|
+
connectorSettingsPage: async ({ page }, use) => {
|
|
113
|
+
await use(new ConnectorSettingsPage_1.ConnectorSettingsPage(page));
|
|
114
|
+
},
|
|
115
|
+
connectorMarketplacePage: async ({ page }, use) => {
|
|
116
|
+
await use(new ConnectorMarketplacePage_1.ConnectorMarketplacePage(page));
|
|
117
|
+
},
|
|
118
|
+
managementIdentityPage: async ({ page }, use) => {
|
|
119
|
+
await use(new ManagementIdentityPage_1.ManagementIdentityPage(page));
|
|
120
|
+
},
|
|
121
|
+
ocIdentityHomePage: async ({ page }, use) => {
|
|
122
|
+
await use(new OCIdentityHomePage_1.OCIdentityHomePage(page));
|
|
123
|
+
},
|
|
124
|
+
ocIdentityMappingRulesPage: async ({ page }, use) => {
|
|
125
|
+
await use(new OCIdentityMappingRulesPage_1.OCIdentityMappingRulesPage(page));
|
|
126
|
+
},
|
|
127
|
+
ocIdentityClusterVariablesPage: async ({ page }, use) => {
|
|
128
|
+
await use(new OCIdentityClusterVariablesPage_1.OCIdentityClusterVariablesPage(page));
|
|
129
|
+
},
|
|
130
|
+
ocIdentityRolesPage: async ({ page }, use) => {
|
|
131
|
+
await use(new OCIdentityRolesPage_1.OCIdentityRolesPage(page));
|
|
132
|
+
},
|
|
133
|
+
ocIdentityAuthorizationsPage: async ({ page }, use) => {
|
|
134
|
+
await use(new OCIdentityAuthorizationsPage_1.OCIdentityAuthorizationsPage(page));
|
|
135
|
+
},
|
|
136
|
+
optimizeDashboardPage: async ({ page }, use) => {
|
|
137
|
+
await use(new OptimizeDashboardPage_1.OptimizeDashboardPage(page));
|
|
138
|
+
},
|
|
139
|
+
taskProcessesPage: async ({ page }, use) => {
|
|
140
|
+
await use(new TaskProcessesPage_1.TaskProcessesPage(page));
|
|
141
|
+
},
|
|
142
|
+
managementIdentityTenantPage: async ({ page }, use) => {
|
|
143
|
+
await use(new IdentityTenantPage_1.IdentityTenantPage(page));
|
|
144
|
+
},
|
|
145
|
+
connectorTemplatePage: async ({ page }, use) => {
|
|
146
|
+
await use(new ConnectorTemplatePage_1.ConnectorTemplatePage(page));
|
|
147
|
+
},
|
|
148
|
+
keycloakLoginPage: async ({ page }, use) => {
|
|
149
|
+
await use(new KeycloakLoginPage_1.KeycloakLoginPage(page));
|
|
150
|
+
},
|
|
151
|
+
keycloakAdminPage: async ({ page }, use) => {
|
|
152
|
+
await use(new KeycloakAdminPage_1.KeycloakAdminPage(page));
|
|
153
|
+
},
|
|
154
|
+
ocIdentityGroupsPage: async ({ page }, use) => {
|
|
155
|
+
await use(new OCIdentityGroupsPage_1.OCIdentityGroupsPage(page));
|
|
156
|
+
},
|
|
157
|
+
ocTenantPage: async ({ page }, use) => {
|
|
158
|
+
await use(new OCTenantPage_1.OCTenantPage(page));
|
|
159
|
+
},
|
|
160
|
+
overrideTrackingScripts: [
|
|
161
|
+
async ({ context }, use) => {
|
|
162
|
+
await context.route('https://cmp.osano.com/16CVvwSNKHi9t1grQ/9403708a-488b-4f3b-aea6-613825dec79f/osano.js', (route) => route.fulfill({
|
|
163
|
+
status: 200,
|
|
164
|
+
headers: {
|
|
165
|
+
'Content-Type': 'text/javascript;charset=UTF-8',
|
|
166
|
+
},
|
|
167
|
+
body: '',
|
|
168
|
+
}));
|
|
169
|
+
await use();
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
auto: true,
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
exports.test = test;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Page, Locator } from '@playwright/test';
|
|
2
|
+
declare class Authorization {
|
|
3
|
+
readonly page: Page;
|
|
4
|
+
protected readonly selectResourceTypeTab: (name: string) => Locator;
|
|
5
|
+
protected readonly createAuthorizationModal: Locator;
|
|
6
|
+
protected readonly createAuthorizationButton: Locator;
|
|
7
|
+
protected readonly createAuthorizationOwnerTypeCombobox: Locator;
|
|
8
|
+
protected readonly createAuthorizationOwnerTypeOption: (name: string) => Locator;
|
|
9
|
+
protected readonly createAuthorizationOwnerComboBox: Locator;
|
|
10
|
+
protected readonly createAuthorizationOwnerOption: (name: string) => Locator;
|
|
11
|
+
protected readonly createAuthorizationOwnerSearchInput: Locator;
|
|
12
|
+
protected readonly createAuthorizationOwnerSearchOption: (name: string) => Locator;
|
|
13
|
+
protected readonly createAuthorizationOwnerCommandInput: Locator;
|
|
14
|
+
protected readonly createAuthorizationOwnerCommandOptions: Locator;
|
|
15
|
+
protected readonly createAuthorizationResourceTypeDropdown: Locator;
|
|
16
|
+
protected readonly createAuthorizationResourceTypeOption: (name: string) => Locator;
|
|
17
|
+
protected readonly createAuthorizationResourceIdField: Locator;
|
|
18
|
+
protected readonly createAuthorizationAccessPermission: (name: string) => Locator;
|
|
19
|
+
protected readonly createAuthorizationSubmitButton: Locator;
|
|
20
|
+
protected readonly authorizationsList: Locator;
|
|
21
|
+
protected readonly deleteAuthorizationButton: (name: string) => Locator;
|
|
22
|
+
protected readonly deleteAuthorizationModal: Locator;
|
|
23
|
+
protected readonly deleteAuthorizationModalDeleteButton: Locator;
|
|
24
|
+
protected readonly tableFilter: Locator;
|
|
25
|
+
constructor(page: Page);
|
|
26
|
+
protected selectResourceType(resourceType: string, timeout?: number): Promise<void>;
|
|
27
|
+
private selectAuthorizationOwner;
|
|
28
|
+
createAuthorization(authorization: {
|
|
29
|
+
ownerType: string;
|
|
30
|
+
ownerId: string;
|
|
31
|
+
resourceType: string;
|
|
32
|
+
resourceId: string;
|
|
33
|
+
accessPermissions: string[];
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
private expectAuthorizationListed;
|
|
36
|
+
private filterAuthorizationsByOwner;
|
|
37
|
+
deleteAuthorization(resourceId: string, resourceType: string): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
export { Authorization };
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Authorization = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
const findLocatorWithPagination_1 = require("../../utils/assertionHelpers/findLocatorWithPagination");
|
|
6
|
+
const submitModalWithRetry_1 = require("../../utils/assertionHelpers/submitModalWithRetry");
|
|
7
|
+
const sleep_1 = require("../../utils/sleep");
|
|
8
|
+
class Authorization {
|
|
9
|
+
page;
|
|
10
|
+
selectResourceTypeTab;
|
|
11
|
+
createAuthorizationModal;
|
|
12
|
+
createAuthorizationButton;
|
|
13
|
+
createAuthorizationOwnerTypeCombobox;
|
|
14
|
+
createAuthorizationOwnerTypeOption;
|
|
15
|
+
createAuthorizationOwnerComboBox;
|
|
16
|
+
createAuthorizationOwnerOption;
|
|
17
|
+
createAuthorizationOwnerSearchInput;
|
|
18
|
+
createAuthorizationOwnerSearchOption;
|
|
19
|
+
createAuthorizationOwnerCommandInput;
|
|
20
|
+
createAuthorizationOwnerCommandOptions;
|
|
21
|
+
createAuthorizationResourceTypeDropdown;
|
|
22
|
+
createAuthorizationResourceTypeOption;
|
|
23
|
+
createAuthorizationResourceIdField;
|
|
24
|
+
createAuthorizationAccessPermission;
|
|
25
|
+
createAuthorizationSubmitButton;
|
|
26
|
+
authorizationsList;
|
|
27
|
+
deleteAuthorizationButton;
|
|
28
|
+
deleteAuthorizationModal;
|
|
29
|
+
deleteAuthorizationModalDeleteButton;
|
|
30
|
+
tableFilter;
|
|
31
|
+
constructor(page) {
|
|
32
|
+
this.page = page;
|
|
33
|
+
this.selectResourceTypeTab = (resourceType) => page.getByRole('tab', { name: resourceType });
|
|
34
|
+
this.authorizationsList = page.getByRole('table');
|
|
35
|
+
this.createAuthorizationButton = page.getByRole('button', {
|
|
36
|
+
name: /create authorization/i,
|
|
37
|
+
});
|
|
38
|
+
this.createAuthorizationModal = page.getByRole('dialog', {
|
|
39
|
+
name: 'Create authorization',
|
|
40
|
+
});
|
|
41
|
+
this.createAuthorizationOwnerTypeCombobox =
|
|
42
|
+
this.createAuthorizationModal.getByRole('combobox', {
|
|
43
|
+
name: 'Owner type',
|
|
44
|
+
});
|
|
45
|
+
// The design-system Select portals its listbox to the end of <body>, so
|
|
46
|
+
// the options are siblings of the dialog rather than descendants, and
|
|
47
|
+
// while the listbox is open Radix marks everything outside it aria-hidden
|
|
48
|
+
// - which takes the dialog itself out of the accessibility tree. Query the
|
|
49
|
+
// options from the page root so both placements resolve.
|
|
50
|
+
this.createAuthorizationOwnerTypeOption = (name) => this.page
|
|
51
|
+
.getByRole('option', {
|
|
52
|
+
name,
|
|
53
|
+
exact: true,
|
|
54
|
+
})
|
|
55
|
+
.first();
|
|
56
|
+
this.createAuthorizationOwnerComboBox =
|
|
57
|
+
this.createAuthorizationModal.getByRole('combobox', {
|
|
58
|
+
name: 'Owner',
|
|
59
|
+
exact: true,
|
|
60
|
+
});
|
|
61
|
+
this.createAuthorizationOwnerOption = (name) => this.createAuthorizationModal.getByRole('option', {
|
|
62
|
+
name,
|
|
63
|
+
exact: true,
|
|
64
|
+
});
|
|
65
|
+
// Every owner type now renders a server-backed search dropdown instead of
|
|
66
|
+
// the combobox that listed all owners up front. The dropdown is a Carbon
|
|
67
|
+
// Search inside a ListBox, so it has no combobox role; its results are
|
|
68
|
+
// list-box menu items that carry the owner ID as their title. The
|
|
69
|
+
// design-system build renders the same field as a command palette whose
|
|
70
|
+
// results are role=option items in a popover portalled out of the dialog.
|
|
71
|
+
this.createAuthorizationOwnerSearchInput =
|
|
72
|
+
this.createAuthorizationModal.getByPlaceholder('Search by owner ID');
|
|
73
|
+
this.createAuthorizationOwnerSearchOption = (name) => this.page
|
|
74
|
+
.locator('.cds--list-box__menu-item, [role="option"]')
|
|
75
|
+
.filter({ hasText: name })
|
|
76
|
+
.first();
|
|
77
|
+
// In the design-system build the closed Owner control is a combobox-role
|
|
78
|
+
// trigger that paints "Search by owner ID" as static text (no placeholder
|
|
79
|
+
// attribute), and the cmdk search box plus its result listbox only mount
|
|
80
|
+
// in a popover once the trigger is opened. That popover is portalled out
|
|
81
|
+
// of the dialog, and while it is open Radix marks the dialog aria-hidden,
|
|
82
|
+
// so both must be queried from the page root.
|
|
83
|
+
this.createAuthorizationOwnerCommandInput = this.page
|
|
84
|
+
.locator('[data-slot="command-input"]')
|
|
85
|
+
.first();
|
|
86
|
+
this.createAuthorizationOwnerCommandOptions = this.page
|
|
87
|
+
.getByRole('listbox')
|
|
88
|
+
.getByRole('option');
|
|
89
|
+
this.createAuthorizationResourceTypeDropdown =
|
|
90
|
+
this.createAuthorizationModal.getByRole('combobox', {
|
|
91
|
+
name: 'Resource type',
|
|
92
|
+
});
|
|
93
|
+
this.createAuthorizationResourceTypeOption = (name) => this.page
|
|
94
|
+
.getByRole('option', {
|
|
95
|
+
name,
|
|
96
|
+
exact: true,
|
|
97
|
+
})
|
|
98
|
+
.first();
|
|
99
|
+
this.createAuthorizationResourceIdField =
|
|
100
|
+
this.createAuthorizationModal.getByRole('textbox', {
|
|
101
|
+
name: 'Resource ID',
|
|
102
|
+
});
|
|
103
|
+
this.createAuthorizationAccessPermission = (name) => this.createAuthorizationModal.locator(`label[for="${name}"]`);
|
|
104
|
+
this.createAuthorizationSubmitButton =
|
|
105
|
+
this.createAuthorizationModal.getByRole('button', {
|
|
106
|
+
name: 'Create authorization',
|
|
107
|
+
});
|
|
108
|
+
this.authorizationsList = page.getByRole('table');
|
|
109
|
+
this.deleteAuthorizationButton = (name) => this.authorizationsList
|
|
110
|
+
.getByRole('row', { name })
|
|
111
|
+
.getByRole('button', { name: 'Delete' });
|
|
112
|
+
this.deleteAuthorizationModal = page.getByRole('dialog', {
|
|
113
|
+
name: /delete authorization/i,
|
|
114
|
+
});
|
|
115
|
+
this.deleteAuthorizationModalDeleteButton =
|
|
116
|
+
this.deleteAuthorizationModal.getByRole('button', {
|
|
117
|
+
name: /delete authorization/i,
|
|
118
|
+
});
|
|
119
|
+
// Carbon labels the table toolbar search "Filter table"; the
|
|
120
|
+
// design-system shell the Admin is migrating onto exposes the placeholder
|
|
121
|
+
// as the accessible name instead. Match either.
|
|
122
|
+
this.tableFilter = page
|
|
123
|
+
.getByRole('searchbox', { name: 'Filter table' })
|
|
124
|
+
.or(page.getByRole('searchbox', { name: 'Search by owner ID' }))
|
|
125
|
+
.first();
|
|
126
|
+
}
|
|
127
|
+
// The Admin's Authorizations page is migrating onto the new design-system
|
|
128
|
+
// shell, which replaces the per-resource-type tabs with a single filter
|
|
129
|
+
// combobox (identity/client ListV2.tsx). That combobox's accessible name was
|
|
130
|
+
// renamed from "Authorization type" to "Resource type" in camunda/camunda
|
|
131
|
+
// commit 377b0e3; match either so both image versions resolve. Select the
|
|
132
|
+
// resource type through whichever this build renders: click the tab, or open
|
|
133
|
+
// the combobox and pick the option.
|
|
134
|
+
async selectResourceType(resourceType, timeout = 60000) {
|
|
135
|
+
const tab = this.selectResourceTypeTab(resourceType);
|
|
136
|
+
const filterCombobox = this.page
|
|
137
|
+
.getByRole('combobox', { name: 'Resource type' })
|
|
138
|
+
.or(this.page.getByRole('combobox', { name: 'Authorization type' }));
|
|
139
|
+
await (0, test_1.expect)(tab.or(filterCombobox)).toBeVisible({ timeout });
|
|
140
|
+
if (await tab.isVisible()) {
|
|
141
|
+
await tab.click();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
await filterCombobox.click();
|
|
145
|
+
await this.page
|
|
146
|
+
.getByRole('option', { name: resourceType, exact: true })
|
|
147
|
+
.click({ timeout: Math.min(timeout, 30000) });
|
|
148
|
+
}
|
|
149
|
+
// Released 8.10 alpha images still render the Carbon combobox that lists
|
|
150
|
+
// every owner, so accept whichever of the three owner fields this build
|
|
151
|
+
// shows: the Carbon search dropdown, the Carbon combobox that lists every
|
|
152
|
+
// owner inline, or the design-system combobox whose cmdk popover only loads
|
|
153
|
+
// results once the owner ID is typed.
|
|
154
|
+
async selectAuthorizationOwner(ownerId) {
|
|
155
|
+
await (0, test_1.expect)(this.createAuthorizationOwnerSearchInput.or(this.createAuthorizationOwnerComboBox)).toBeVisible({ timeout: 30000 });
|
|
156
|
+
if (await this.createAuthorizationOwnerSearchInput.isVisible()) {
|
|
157
|
+
await this.createAuthorizationOwnerSearchInput.fill(ownerId);
|
|
158
|
+
const ownerOption = this.createAuthorizationOwnerSearchOption(ownerId);
|
|
159
|
+
// The search is debounced and served by the API, so a just-created
|
|
160
|
+
// owner can take a while to surface.
|
|
161
|
+
await (0, test_1.expect)(ownerOption).toBeVisible({ timeout: 60000 });
|
|
162
|
+
await ownerOption.click({ timeout: 30000 });
|
|
163
|
+
// Picking an owner replaces the search input with a tag holding the
|
|
164
|
+
// selection, which is how we know the choice was committed.
|
|
165
|
+
await (0, test_1.expect)(this.createAuthorizationOwnerSearchInput).toBeHidden({
|
|
166
|
+
timeout: 30000,
|
|
167
|
+
});
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
await this.createAuthorizationOwnerComboBox.click();
|
|
171
|
+
const commandInput = this.createAuthorizationOwnerCommandInput;
|
|
172
|
+
const inlineOwnerOption = this.createAuthorizationOwnerOption(ownerId);
|
|
173
|
+
await (0, test_1.expect)(commandInput.or(inlineOwnerOption).first()).toBeVisible({
|
|
174
|
+
timeout: 30000,
|
|
175
|
+
});
|
|
176
|
+
if (await commandInput.isVisible()) {
|
|
177
|
+
await commandInput.fill(ownerId);
|
|
178
|
+
// The result list is served by the API and debounced, and each option is
|
|
179
|
+
// labelled "<owner id> — <name>" rather than the bare ID, so narrow the
|
|
180
|
+
// search to the single row this unique owner ID resolves to instead of
|
|
181
|
+
// matching on the label text.
|
|
182
|
+
const ownerOptions = this.createAuthorizationOwnerCommandOptions;
|
|
183
|
+
await (0, test_1.expect)(ownerOptions).toHaveCount(1, { timeout: 60000 });
|
|
184
|
+
await ownerOptions.first().click({ timeout: 30000, force: true });
|
|
185
|
+
// Committing the choice closes the popover, which is what hands the
|
|
186
|
+
// dialog back to the accessibility tree for the fields that follow.
|
|
187
|
+
await (0, test_1.expect)(commandInput).toBeHidden({ timeout: 30000 });
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
await (0, test_1.expect)(inlineOwnerOption).toBeVisible({
|
|
191
|
+
timeout: 30000,
|
|
192
|
+
});
|
|
193
|
+
await inlineOwnerOption.click({
|
|
194
|
+
timeout: 30000,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
async createAuthorization(authorization) {
|
|
198
|
+
await this.createAuthorizationButton.click();
|
|
199
|
+
await (0, test_1.expect)(this.createAuthorizationModal).toBeVisible();
|
|
200
|
+
await this.createAuthorizationOwnerTypeCombobox.click();
|
|
201
|
+
await this.createAuthorizationOwnerTypeOption(authorization.ownerType).click();
|
|
202
|
+
await this.selectAuthorizationOwner(authorization.ownerId);
|
|
203
|
+
// The Resource type is pre-selected and disabled when the dialog is
|
|
204
|
+
// opened from a specific resource-type tab. Only pick it from the dropdown
|
|
205
|
+
// when the field is still enabled (editable).
|
|
206
|
+
await (0, test_1.expect)(this.createAuthorizationResourceTypeDropdown).toBeVisible({
|
|
207
|
+
timeout: 30000,
|
|
208
|
+
});
|
|
209
|
+
if (await this.createAuthorizationResourceTypeDropdown.isEnabled()) {
|
|
210
|
+
await this.createAuthorizationResourceTypeDropdown.click();
|
|
211
|
+
await this.createAuthorizationResourceTypeOption(authorization.resourceType).click({ timeout: 30000 });
|
|
212
|
+
}
|
|
213
|
+
await this.createAuthorizationResourceIdField.fill(authorization.resourceId);
|
|
214
|
+
for (const permission of authorization.accessPermissions) {
|
|
215
|
+
await (0, sleep_1.sleep)(200);
|
|
216
|
+
const permissionLabel = this.createAuthorizationAccessPermission(permission);
|
|
217
|
+
const permissionInput = this.createAuthorizationModal.locator(`input[id="${permission}"], [role="checkbox"][id="${permission}"]`);
|
|
218
|
+
await (0, test_1.expect)(permissionLabel).toBeVisible();
|
|
219
|
+
if (!(await permissionInput.isChecked())) {
|
|
220
|
+
await permissionLabel.scrollIntoViewIfNeeded();
|
|
221
|
+
await (0, sleep_1.sleep)(300);
|
|
222
|
+
let clickAttempts = 0;
|
|
223
|
+
const maxAttempts = 3;
|
|
224
|
+
while (!(await permissionInput.isChecked()) &&
|
|
225
|
+
clickAttempts < maxAttempts) {
|
|
226
|
+
clickAttempts++;
|
|
227
|
+
await permissionLabel.click({ force: true });
|
|
228
|
+
await (0, sleep_1.sleep)(500);
|
|
229
|
+
if (await permissionInput.isChecked()) {
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
if (clickAttempts < maxAttempts) {
|
|
233
|
+
await permissionLabel.click();
|
|
234
|
+
await (0, sleep_1.sleep)(300);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
await (0, test_1.expect)(permissionInput).toBeChecked({ timeout: 3000 });
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
await (0, submitModalWithRetry_1.submitModalWithRetry)(this.createAuthorizationSubmitButton, this.createAuthorizationModal);
|
|
241
|
+
await this.selectResourceType(authorization.resourceType);
|
|
242
|
+
const item = this.page
|
|
243
|
+
.getByRole('row')
|
|
244
|
+
.filter({
|
|
245
|
+
hasText: `${authorization.ownerId}${authorization.resourceId}`,
|
|
246
|
+
})
|
|
247
|
+
.first();
|
|
248
|
+
await this.expectAuthorizationListed(authorization, item);
|
|
249
|
+
}
|
|
250
|
+
// The toolbar search filters by owner ID, so filling it with the resource
|
|
251
|
+
// type narrowed nothing, and the retry helper it fed reloads before it
|
|
252
|
+
// asserts, which dropped the filter entirely. That left the new row to be
|
|
253
|
+
// found on page 1 of the unfiltered table - and the authorizations table
|
|
254
|
+
// paginates, so with the RBA specs creating owners in parallel it is
|
|
255
|
+
// regularly on a later page. Filter by owner, then page through what is
|
|
256
|
+
// left; fall back to the unfiltered table for builds whose search has not
|
|
257
|
+
// caught up with a just-created owner yet.
|
|
258
|
+
async expectAuthorizationListed(authorization, item) {
|
|
259
|
+
const deadline = Date.now() + 180000;
|
|
260
|
+
const budget = (max) => Math.max(5000, Math.min(max, deadline - Date.now()));
|
|
261
|
+
const maxAttempts = 5;
|
|
262
|
+
let lastError;
|
|
263
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
264
|
+
if (attempt > 0 && Date.now() >= deadline) {
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
await this.selectResourceType(authorization.resourceType, budget(30000));
|
|
269
|
+
for (const filterValue of [authorization.ownerId, '']) {
|
|
270
|
+
await this.filterAuthorizationsByOwner(filterValue);
|
|
271
|
+
const found = await (0, findLocatorWithPagination_1.findLocatorWithPagination)(this.page, item, {
|
|
272
|
+
timeout: budget(filterValue === '' ? 45000 : 15000),
|
|
273
|
+
});
|
|
274
|
+
if (found) {
|
|
275
|
+
await (0, test_1.expect)(item).toBeVisible({ timeout: 5000 });
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
throw new Error(`No row for owner "${authorization.ownerId}" and resource ` +
|
|
280
|
+
`"${authorization.resourceId}" in the ` +
|
|
281
|
+
`${authorization.resourceType} table`);
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
lastError = error;
|
|
285
|
+
if (attempt < maxAttempts - 1) {
|
|
286
|
+
console.warn(`Attempt ${attempt + 1} did not list the ` +
|
|
287
|
+
`${authorization.resourceType} authorization for ` +
|
|
288
|
+
`"${authorization.ownerId}". Retrying...`);
|
|
289
|
+
// A refused/reset connection while the gateway restarts must feed
|
|
290
|
+
// the next attempt, not abort the retry loop.
|
|
291
|
+
await this.page
|
|
292
|
+
.reload({ waitUntil: 'domcontentloaded' })
|
|
293
|
+
.catch((reloadError) => {
|
|
294
|
+
lastError = reloadError;
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
throw new Error(`Authorization for "${authorization.ownerId}" on ` +
|
|
300
|
+
`"${authorization.resourceId}" was not listed: ${String(lastError)}`);
|
|
301
|
+
}
|
|
302
|
+
async filterAuthorizationsByOwner(ownerId) {
|
|
303
|
+
const hasFilter = await this.tableFilter
|
|
304
|
+
.isVisible({ timeout: 5000 })
|
|
305
|
+
.catch(() => false);
|
|
306
|
+
if (!hasFilter) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
await this.tableFilter.fill(ownerId);
|
|
310
|
+
await (0, sleep_1.sleep)(1000);
|
|
311
|
+
}
|
|
312
|
+
async deleteAuthorization(resourceId, resourceType) {
|
|
313
|
+
// Same paginated table as createAuthorization: the row being deleted is
|
|
314
|
+
// not necessarily on page 1, and the toolbar search cannot narrow by
|
|
315
|
+
// resource ID.
|
|
316
|
+
const found = await (0, findLocatorWithPagination_1.findLocatorWithPagination)(this.page, this.deleteAuthorizationButton(resourceId), { timeout: 60000 });
|
|
317
|
+
if (!found) {
|
|
318
|
+
throw new Error(`No ${resourceType} authorization row for resource "${resourceId}"`);
|
|
319
|
+
}
|
|
320
|
+
await this.deleteAuthorizationButton(resourceId).click();
|
|
321
|
+
await (0, test_1.expect)(this.deleteAuthorizationModal).toBeVisible();
|
|
322
|
+
await this.deleteAuthorizationModalDeleteButton.click();
|
|
323
|
+
await (0, test_1.expect)(this.deleteAuthorizationModal).not.toBeVisible();
|
|
324
|
+
// Re-selecting the resource type takes two interactions on the
|
|
325
|
+
// design-system build, so this cannot go through the shared
|
|
326
|
+
// reload-click-assert helper, which only accepts a single click locator.
|
|
327
|
+
const deletedCell = this.authorizationsList
|
|
328
|
+
.getByRole('cell', { name: resourceId })
|
|
329
|
+
.first();
|
|
330
|
+
let lastError;
|
|
331
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
332
|
+
await this.page.reload();
|
|
333
|
+
await this.page.waitForLoadState('domcontentloaded');
|
|
334
|
+
await this.selectResourceType(resourceType);
|
|
335
|
+
try {
|
|
336
|
+
await (0, test_1.expect)(deletedCell).not.toBeVisible({ timeout: 5000 });
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
catch (error) {
|
|
340
|
+
lastError = error;
|
|
341
|
+
console.warn(`Attempt ${attempt + 1} still listed the ${resourceType} ` +
|
|
342
|
+
`authorization for "${resourceId}". Retrying...`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
throw new Error(`Authorization for resource "${resourceId}" is still listed: ` +
|
|
346
|
+
String(lastError));
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
exports.Authorization = Authorization;
|