@red-hat-developer-hub/e2e-test-utils 1.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +6 -0
  3. package/dist/deployment/keycloak/config/keycloak-values.yaml +96 -0
  4. package/dist/deployment/keycloak/constants.d.ts +29 -0
  5. package/dist/deployment/keycloak/constants.d.ts.map +1 -0
  6. package/dist/deployment/keycloak/constants.js +75 -0
  7. package/dist/deployment/keycloak/deployment.d.ts +89 -0
  8. package/dist/deployment/keycloak/deployment.d.ts.map +1 -0
  9. package/dist/deployment/keycloak/deployment.js +435 -0
  10. package/dist/deployment/keycloak/index.d.ts +2 -0
  11. package/dist/deployment/keycloak/index.d.ts.map +1 -0
  12. package/dist/deployment/keycloak/index.js +1 -0
  13. package/dist/deployment/keycloak/types.d.ts +59 -0
  14. package/dist/deployment/keycloak/types.d.ts.map +1 -0
  15. package/dist/deployment/keycloak/types.js +1 -0
  16. package/dist/deployment/rhdh/config/auth/guest/app-config.yaml +5 -0
  17. package/dist/deployment/rhdh/config/auth/keycloak/app-config.yaml +19 -0
  18. package/dist/deployment/rhdh/config/auth/keycloak/dynamic-plugins.yaml +3 -0
  19. package/dist/deployment/rhdh/config/auth/keycloak/secrets.yaml +12 -0
  20. package/dist/deployment/rhdh/config/common/app-config-rhdh.yaml +6 -0
  21. package/dist/deployment/rhdh/config/common/dynamic-plugins.yaml +3 -0
  22. package/dist/deployment/rhdh/config/common/rhdh-secrets.yaml +7 -0
  23. package/dist/deployment/rhdh/config/helm/value_file.yaml +7 -0
  24. package/dist/deployment/rhdh/config/operator/subscription.yaml +21 -0
  25. package/dist/deployment/rhdh/constants.d.ts +19 -0
  26. package/dist/deployment/rhdh/constants.d.ts.map +1 -0
  27. package/dist/deployment/rhdh/constants.js +27 -0
  28. package/dist/deployment/rhdh/deployment.d.ts +40 -0
  29. package/dist/deployment/rhdh/deployment.d.ts.map +1 -0
  30. package/dist/deployment/rhdh/deployment.js +303 -0
  31. package/dist/deployment/rhdh/index.d.ts +2 -0
  32. package/dist/deployment/rhdh/index.d.ts.map +1 -0
  33. package/dist/deployment/rhdh/index.js +1 -0
  34. package/dist/deployment/rhdh/types.d.ts +31 -0
  35. package/dist/deployment/rhdh/types.d.ts.map +1 -0
  36. package/dist/deployment/rhdh/types.js +1 -0
  37. package/dist/eslint/base.config.d.ts +10 -0
  38. package/dist/eslint/base.config.d.ts.map +1 -0
  39. package/dist/eslint/base.config.js +213 -0
  40. package/dist/playwright/base-config.d.ts +14 -0
  41. package/dist/playwright/base-config.d.ts.map +1 -0
  42. package/dist/playwright/base-config.js +47 -0
  43. package/dist/playwright/fixtures/test.d.ts +13 -0
  44. package/dist/playwright/fixtures/test.d.ts.map +1 -0
  45. package/dist/playwright/fixtures/test.js +48 -0
  46. package/dist/playwright/global-setup.d.ts +6 -0
  47. package/dist/playwright/global-setup.d.ts.map +1 -0
  48. package/dist/playwright/global-setup.js +67 -0
  49. package/dist/playwright/helpers/accessibility.d.ts +13 -0
  50. package/dist/playwright/helpers/accessibility.d.ts.map +1 -0
  51. package/dist/playwright/helpers/accessibility.js +24 -0
  52. package/dist/playwright/helpers/api-endpoints.d.ts +11 -0
  53. package/dist/playwright/helpers/api-endpoints.d.ts.map +1 -0
  54. package/dist/playwright/helpers/api-endpoints.js +15 -0
  55. package/dist/playwright/helpers/api-helper.d.ts +77 -0
  56. package/dist/playwright/helpers/api-helper.d.ts.map +1 -0
  57. package/dist/playwright/helpers/api-helper.js +285 -0
  58. package/dist/playwright/helpers/common.d.ts +31 -0
  59. package/dist/playwright/helpers/common.d.ts.map +1 -0
  60. package/dist/playwright/helpers/common.js +342 -0
  61. package/dist/playwright/helpers/index.d.ts +5 -0
  62. package/dist/playwright/helpers/index.d.ts.map +1 -0
  63. package/dist/playwright/helpers/index.js +4 -0
  64. package/dist/playwright/helpers/navbar.d.ts +2 -0
  65. package/dist/playwright/helpers/navbar.d.ts.map +1 -0
  66. package/dist/playwright/helpers/navbar.js +1 -0
  67. package/dist/playwright/helpers/ui-helper.d.ts +106 -0
  68. package/dist/playwright/helpers/ui-helper.d.ts.map +1 -0
  69. package/dist/playwright/helpers/ui-helper.js +439 -0
  70. package/dist/playwright/page-objects/global-obj.d.ts +25 -0
  71. package/dist/playwright/page-objects/global-obj.d.ts.map +1 -0
  72. package/dist/playwright/page-objects/global-obj.js +24 -0
  73. package/dist/playwright/page-objects/page-obj.d.ts +41 -0
  74. package/dist/playwright/page-objects/page-obj.d.ts.map +1 -0
  75. package/dist/playwright/page-objects/page-obj.js +40 -0
  76. package/dist/playwright/pages/catalog-import.d.ts +31 -0
  77. package/dist/playwright/pages/catalog-import.d.ts.map +1 -0
  78. package/dist/playwright/pages/catalog-import.js +65 -0
  79. package/dist/playwright/pages/catalog.d.ts +14 -0
  80. package/dist/playwright/pages/catalog.d.ts.map +1 -0
  81. package/dist/playwright/pages/catalog.js +37 -0
  82. package/dist/playwright/pages/extensions.d.ts +38 -0
  83. package/dist/playwright/pages/extensions.d.ts.map +1 -0
  84. package/dist/playwright/pages/extensions.js +110 -0
  85. package/dist/playwright/pages/home-page.d.ts +10 -0
  86. package/dist/playwright/pages/home-page.d.ts.map +1 -0
  87. package/dist/playwright/pages/home-page.js +46 -0
  88. package/dist/playwright/pages/index.d.ts +6 -0
  89. package/dist/playwright/pages/index.d.ts.map +1 -0
  90. package/dist/playwright/pages/index.js +5 -0
  91. package/dist/playwright/pages/notifications.d.ts +24 -0
  92. package/dist/playwright/pages/notifications.d.ts.map +1 -0
  93. package/dist/playwright/pages/notifications.js +112 -0
  94. package/dist/utils/bash.d.ts +3 -0
  95. package/dist/utils/bash.d.ts.map +1 -0
  96. package/dist/utils/bash.js +4 -0
  97. package/dist/utils/common.d.ts +3 -0
  98. package/dist/utils/common.d.ts.map +1 -0
  99. package/dist/utils/common.js +8 -0
  100. package/dist/utils/index.d.ts +5 -0
  101. package/dist/utils/index.d.ts.map +1 -0
  102. package/dist/utils/index.js +4 -0
  103. package/dist/utils/kubernetes-client.d.ts +97 -0
  104. package/dist/utils/kubernetes-client.d.ts.map +1 -0
  105. package/dist/utils/kubernetes-client.js +558 -0
  106. package/dist/utils/merge-yamls.d.ts +50 -0
  107. package/dist/utils/merge-yamls.d.ts.map +1 -0
  108. package/dist/utils/merge-yamls.js +96 -0
  109. package/dist/utils/plugin-metadata.d.ts +116 -0
  110. package/dist/utils/plugin-metadata.d.ts.map +1 -0
  111. package/dist/utils/plugin-metadata.js +330 -0
  112. package/package.json +108 -0
  113. package/tsconfig.base.json +16 -0
@@ -0,0 +1,14 @@
1
+ import type { Locator, Page } from "@playwright/test";
2
+ export declare class CatalogPage {
3
+ private page;
4
+ private uiHelper;
5
+ private searchField;
6
+ constructor(page: Page);
7
+ go(): Promise<void>;
8
+ goToByName(name: string): Promise<void>;
9
+ goToBackstageJanusProjectCITab(): Promise<void>;
10
+ goToBackstageJanusProject(): Promise<void>;
11
+ search(s: string): Promise<void>;
12
+ tableRow(content: string): Promise<Locator>;
13
+ }
14
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../../src/playwright/pages/catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAItD,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,WAAW,CAAU;gBAEjB,IAAI,EAAE,IAAI;IAMhB,EAAE;IAIF,UAAU,CAAC,IAAI,EAAE,MAAM;IAKvB,8BAA8B;IAO9B,yBAAyB;IAIzB,MAAM,CAAC,CAAC,EAAE,MAAM;IAShB,QAAQ,CAAC,OAAO,EAAE,MAAM;CAG/B"}
@@ -0,0 +1,37 @@
1
+ import { UIhelper } from "../helpers/ui-helper.js";
2
+ //${BASE_URL}/catalog page
3
+ export class CatalogPage {
4
+ page;
5
+ uiHelper;
6
+ searchField;
7
+ constructor(page) {
8
+ this.page = page;
9
+ this.uiHelper = new UIhelper(page);
10
+ this.searchField = page.locator("#input-with-icon-adornment");
11
+ }
12
+ async go() {
13
+ await this.uiHelper.openSidebar("Catalog");
14
+ }
15
+ async goToByName(name) {
16
+ await this.uiHelper.openCatalogSidebar("Component");
17
+ await this.uiHelper.clickLink(name);
18
+ }
19
+ async goToBackstageJanusProjectCITab() {
20
+ await this.goToBackstageJanusProject();
21
+ await this.uiHelper.clickTab("CI");
22
+ await this.page.waitForSelector('h2:text("Pipeline Runs")');
23
+ await this.uiHelper.verifyHeading("Pipeline Runs");
24
+ }
25
+ async goToBackstageJanusProject() {
26
+ await this.goToByName("backstage-janus");
27
+ }
28
+ async search(s) {
29
+ await this.searchField.clear();
30
+ const searchResponse = this.page.waitForResponse(new RegExp(`${process.env.BASE_URL}/api/catalog/entities/by-query/*`));
31
+ await this.searchField.fill(s);
32
+ await searchResponse;
33
+ }
34
+ async tableRow(content) {
35
+ return this.page.locator(`tr >> a >> text="${content}"`);
36
+ }
37
+ }
@@ -0,0 +1,38 @@
1
+ import type { Page, Locator } from "@playwright/test";
2
+ export declare class ExtensionsPage {
3
+ private page;
4
+ badge: Locator;
5
+ private uiHelper;
6
+ private commonHeadings;
7
+ private tableHeaders;
8
+ constructor(page: Page);
9
+ clickReadMoreByPluginTitle(pluginTitle: string): Promise<void>;
10
+ selectDropdown(name: string): Promise<void>;
11
+ toggleOption(name: string): Promise<void>;
12
+ clickAway(): Promise<void>;
13
+ selectSupportTypeFilter(supportType: string): Promise<void>;
14
+ resetSupportTypeFilter(supportType: string): Promise<void>;
15
+ verifyMultipleHeadings(headings?: string[]): Promise<void>;
16
+ waitForSearchResults(searchText: string): Promise<void>;
17
+ verifyPluginDetails({ pluginName, badgeLabel, badgeText, headings, includeTable, includeAbout, }: {
18
+ pluginName: string;
19
+ badgeLabel: string;
20
+ badgeText: string;
21
+ headings?: string[];
22
+ includeTable?: boolean;
23
+ includeAbout?: boolean;
24
+ }): Promise<void>;
25
+ verifySupportTypeBadge({ supportType, pluginName, badgeLabel, badgeText, tooltipText, searchTerm, headings, includeTable, includeAbout, }: {
26
+ supportType: string;
27
+ pluginName?: string;
28
+ badgeLabel: string;
29
+ badgeText: string;
30
+ tooltipText: string;
31
+ searchTerm?: string;
32
+ headings?: string[];
33
+ includeTable?: boolean;
34
+ includeAbout?: boolean;
35
+ }): Promise<void>;
36
+ verifyKeyValueRowElements(rowTitle: string, rowValue: string): Promise<void>;
37
+ }
38
+ //# sourceMappingURL=extensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../../src/playwright/pages/extensions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAItD,qBAAa,cAAc;IACzB,OAAO,CAAC,IAAI,CAAO;IACZ,KAAK,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAW;IAE3B,OAAO,CAAC,cAAc,CAOpB;IACF,OAAO,CAAC,YAAY,CAMlB;gBAEU,IAAI,EAAE,IAAI;IAMhB,0BAA0B,CAAC,WAAW,EAAE,MAAM;IAM9C,cAAc,CAAC,IAAI,EAAE,MAAM;IAO3B,YAAY,CAAC,IAAI,EAAE,MAAM;IAOzB,SAAS;IAIT,uBAAuB,CAAC,WAAW,EAAE,MAAM;IAM3C,sBAAsB,CAAC,WAAW,EAAE,MAAM;IAM1C,sBAAsB,CAAC,QAAQ,GAAE,MAAM,EAAwB;IAO/D,oBAAoB,CAAC,UAAU,EAAE,MAAM;IAMvC,mBAAmB,CAAC,EACxB,UAAU,EACV,UAAU,EACV,SAAS,EACT,QAA8B,EAC9B,YAAmB,EACnB,YAAoB,GACrB,EAAE;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB;IAuBK,sBAAsB,CAAC,EAC3B,WAAW,EACX,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,UAAU,EACV,QAA8B,EAC9B,YAAmB,EACnB,YAAoB,GACrB,EAAE;QACD,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB;IA2BK,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAMnE"}
@@ -0,0 +1,110 @@
1
+ import { expect } from "@playwright/test";
2
+ import { UIhelper } from "../helpers/ui-helper.js";
3
+ export class ExtensionsPage {
4
+ page;
5
+ badge;
6
+ uiHelper;
7
+ commonHeadings = [
8
+ "Versions",
9
+ "Author",
10
+ "Tags",
11
+ "Category",
12
+ "Publisher",
13
+ "Support Provider",
14
+ ];
15
+ tableHeaders = [
16
+ "Package name",
17
+ "Version",
18
+ "Role",
19
+ "Backstage compatibility version",
20
+ "Status",
21
+ ];
22
+ constructor(page) {
23
+ this.page = page;
24
+ this.badge = this.page.getByTestId("TaskAltIcon");
25
+ this.uiHelper = new UIhelper(page);
26
+ }
27
+ async clickReadMoreByPluginTitle(pluginTitle) {
28
+ const allCards = this.page.locator(".v5-MuiPaper-outlined");
29
+ const targetCard = allCards.filter({ hasText: pluginTitle });
30
+ await targetCard.getByRole("link", { name: "Read more" }).click();
31
+ }
32
+ async selectDropdown(name) {
33
+ await this.page
34
+ .getByLabel(name)
35
+ .getByRole("button", { name: "Open" })
36
+ .click();
37
+ }
38
+ async toggleOption(name) {
39
+ await this.page
40
+ .getByRole("option", { name: name })
41
+ .getByRole("checkbox")
42
+ .click();
43
+ }
44
+ async clickAway() {
45
+ await this.page.locator("#menu- div").first().click();
46
+ }
47
+ async selectSupportTypeFilter(supportType) {
48
+ await this.selectDropdown("Support type");
49
+ await this.toggleOption(supportType);
50
+ await this.page.keyboard.press("Escape");
51
+ }
52
+ async resetSupportTypeFilter(supportType) {
53
+ await this.selectDropdown("Support type");
54
+ await this.toggleOption(supportType);
55
+ await this.page.keyboard.press("Escape");
56
+ }
57
+ async verifyMultipleHeadings(headings = this.commonHeadings) {
58
+ for (const heading of headings) {
59
+ console.log(`Verifying heading: ${heading}`);
60
+ await this.uiHelper.verifyHeading(heading);
61
+ }
62
+ }
63
+ async waitForSearchResults(searchText) {
64
+ await expect(this.page.locator(".v5-MuiPaper-outlined").first()).toContainText(searchText, { timeout: 10000 });
65
+ }
66
+ async verifyPluginDetails({ pluginName, badgeLabel, badgeText, headings = this.commonHeadings, includeTable = true, includeAbout = false, }) {
67
+ await this.clickReadMoreByPluginTitle(pluginName);
68
+ await expect(this.page.getByLabel(badgeLabel).getByText(badgeText)).toBeVisible();
69
+ if (includeAbout) {
70
+ await this.uiHelper.verifyText("About");
71
+ }
72
+ await this.verifyMultipleHeadings(headings);
73
+ if (includeTable) {
74
+ await this.uiHelper.verifyTableHeadingAndRows(this.tableHeaders);
75
+ }
76
+ await this.page
77
+ .getByRole("button", {
78
+ name: "close",
79
+ })
80
+ .click();
81
+ }
82
+ async verifySupportTypeBadge({ supportType, pluginName, badgeLabel, badgeText, tooltipText, searchTerm, headings = this.commonHeadings, includeTable = true, includeAbout = false, }) {
83
+ await this.selectSupportTypeFilter(supportType);
84
+ if (searchTerm) {
85
+ await this.uiHelper.searchInputPlaceholder(searchTerm);
86
+ await this.waitForSearchResults(searchTerm);
87
+ }
88
+ if (pluginName) {
89
+ await this.verifyPluginDetails({
90
+ pluginName,
91
+ badgeLabel,
92
+ badgeText,
93
+ headings,
94
+ includeTable,
95
+ includeAbout,
96
+ });
97
+ }
98
+ else {
99
+ await expect(this.page.getByLabel(badgeLabel).first()).toBeVisible();
100
+ await expect(this.badge.first()).toBeVisible();
101
+ await this.badge.first().hover();
102
+ await this.uiHelper.verifyTextInTooltip(tooltipText);
103
+ }
104
+ await this.resetSupportTypeFilter(supportType);
105
+ }
106
+ async verifyKeyValueRowElements(rowTitle, rowValue) {
107
+ const rowLocator = this.page.locator(".v5-MuiTableRow-root");
108
+ await expect(rowLocator.filter({ hasText: rowTitle })).toContainText(rowValue);
109
+ }
110
+ }
@@ -0,0 +1,10 @@
1
+ import type { Page } from "@playwright/test";
2
+ export declare class HomePage {
3
+ private page;
4
+ private uiHelper;
5
+ constructor(page: Page);
6
+ verifyQuickSearchBar(text: string): Promise<void>;
7
+ verifyQuickAccess(section: string, quickAccessItem: string, expand?: boolean): Promise<void>;
8
+ verifyVisitedCardContent(section: string): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=home-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home-page.d.ts","sourceRoot":"","sources":["../../../src/playwright/pages/home-page.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG7C,qBAAa,QAAQ;IACnB,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,QAAQ,CAAW;gBAEf,IAAI,EAAE,IAAI;IAIhB,oBAAoB,CAAC,IAAI,EAAE,MAAM;IAUjC,iBAAiB,CACrB,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,MAAM,UAAQ;IAyBV,wBAAwB,CAAC,OAAO,EAAE,MAAM;CAY/C"}
@@ -0,0 +1,46 @@
1
+ import { HOME_PAGE_COMPONENTS, SEARCH_OBJECTS_COMPONENTS, } from "../page-objects/page-obj.js";
2
+ import { UIhelper } from "../helpers/ui-helper.js";
3
+ import { expect } from "@playwright/test";
4
+ export class HomePage {
5
+ page;
6
+ uiHelper;
7
+ constructor(page) {
8
+ this.page = page;
9
+ this.uiHelper = new UIhelper(page);
10
+ }
11
+ async verifyQuickSearchBar(text) {
12
+ const searchBar = this.page.locator(SEARCH_OBJECTS_COMPONENTS.ariaLabelSearch);
13
+ await searchBar.waitFor();
14
+ await searchBar.fill("");
15
+ await searchBar.type(text + "\n"); // '\n' simulates pressing the Enter key
16
+ await this.uiHelper.verifyLink(text);
17
+ }
18
+ async verifyQuickAccess(section, quickAccessItem, expand = false) {
19
+ await this.page.waitForSelector(HOME_PAGE_COMPONENTS.MuiAccordion, {
20
+ state: "visible",
21
+ });
22
+ const sectionLocator = this.page
23
+ .locator(HOME_PAGE_COMPONENTS.MuiAccordion)
24
+ .filter({ hasText: section });
25
+ if (expand) {
26
+ await sectionLocator.click();
27
+ await this.page.waitForTimeout(500);
28
+ }
29
+ const itemLocator = sectionLocator
30
+ .locator(`a div[class*="MuiListItemText-root"]`)
31
+ .filter({ hasText: quickAccessItem });
32
+ await itemLocator.waitFor({ state: "visible" });
33
+ const isVisible = itemLocator;
34
+ await expect(isVisible).toBeVisible();
35
+ }
36
+ async verifyVisitedCardContent(section) {
37
+ await this.page.waitForSelector(HOME_PAGE_COMPONENTS.MuiCard, {
38
+ state: "visible",
39
+ });
40
+ const sectionLocator = this.page
41
+ .locator(HOME_PAGE_COMPONENTS.MuiCard)
42
+ .filter({ hasText: section });
43
+ const itemLocator = sectionLocator.locator(`li[class*="MuiListItem-root"]`);
44
+ expect(await itemLocator.count()).toBeGreaterThanOrEqual(0);
45
+ }
46
+ }
@@ -0,0 +1,6 @@
1
+ export { CatalogImportPage } from "./catalog-import.js";
2
+ export { CatalogPage } from "./catalog.js";
3
+ export { ExtensionsPage } from "./extensions.js";
4
+ export { HomePage } from "./home-page.js";
5
+ export { NotificationPage } from "./notifications.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/playwright/pages/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { CatalogImportPage } from "./catalog-import.js";
2
+ export { CatalogPage } from "./catalog.js";
3
+ export { ExtensionsPage } from "./extensions.js";
4
+ export { HomePage } from "./home-page.js";
5
+ export { NotificationPage } from "./notifications.js";
@@ -0,0 +1,24 @@
1
+ import { type Page } from "@playwright/test";
2
+ export declare class NotificationPage {
3
+ private readonly page;
4
+ private readonly uiHelper;
5
+ constructor(page: Page);
6
+ clickNotificationsNavBarItem(): Promise<void>;
7
+ notificationContains(text: string | RegExp): Promise<void>;
8
+ clickNotificationHeadingLink(text: string | RegExp): Promise<void>;
9
+ markAllNotificationsAsRead(): Promise<void>;
10
+ selectAllNotifications(): Promise<void>;
11
+ selectNotification(nth?: number): Promise<void>;
12
+ selectSeverity(severity?: string): Promise<void>;
13
+ saveSelected(): Promise<void>;
14
+ saveAllSelected(): Promise<void>;
15
+ viewSaved(): Promise<void>;
16
+ markLastNotificationAsRead(): Promise<void>;
17
+ markNotificationAsRead(text: string): Promise<void>;
18
+ markLastNotificationAsUnRead(): Promise<void>;
19
+ viewRead(): Promise<void>;
20
+ viewUnRead(): Promise<void>;
21
+ sortByOldestOnTop(): Promise<void>;
22
+ sortByNewestOnTop(): Promise<void>;
23
+ }
24
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../../src/playwright/pages/notifications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAGrD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;gBAExB,IAAI,EAAE,IAAI;IAKhB,4BAA4B;IAO5B,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAW1C,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAOlD,0BAA0B;IAiB1B,sBAAsB;IAItB,kBAAkB,CAAC,GAAG,SAAI;IAI1B,cAAc,CAAC,QAAQ,SAAK;IAW5B,YAAY;IAWZ,eAAe;IAWf,SAAS;IAQT,0BAA0B;IAK1B,sBAAsB,CAAC,IAAI,EAAE,MAAM;IAKnC,4BAA4B;IAK5B,QAAQ;IAUR,UAAU;IAUV,iBAAiB;IAQjB,iBAAiB;CAOxB"}
@@ -0,0 +1,112 @@
1
+ import { expect } from "@playwright/test";
2
+ import { UIhelper } from "../helpers/ui-helper.js";
3
+ export class NotificationPage {
4
+ page;
5
+ uiHelper;
6
+ constructor(page) {
7
+ this.page = page;
8
+ this.uiHelper = new UIhelper(page);
9
+ }
10
+ async clickNotificationsNavBarItem() {
11
+ await this.uiHelper.openSidebar("Notifications");
12
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
13
+ }
14
+ async notificationContains(text) {
15
+ await this.page.getByLabel(/.*rows/).click();
16
+ // always expand the notifications table to show as many notifications as possible
17
+ await this.page.getByRole("option", { name: "20" }).click();
18
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
19
+ const row = this.page.locator(`tr`, { hasText: text }).first();
20
+ await expect(row).toHaveCount(1);
21
+ }
22
+ async clickNotificationHeadingLink(text) {
23
+ await this.page
24
+ .getByRole("cell", { name: text, exact: true })
25
+ .first()
26
+ .getByRole("heading")
27
+ .click();
28
+ }
29
+ async markAllNotificationsAsRead() {
30
+ const markAllNotificationsAsReadIsVisible = await this.page
31
+ .getByTitle("Mark all read")
32
+ .getByRole("button")
33
+ .isVisible();
34
+ console.log(markAllNotificationsAsReadIsVisible);
35
+ // If button isn't visible there are no records in the notification table
36
+ if (markAllNotificationsAsReadIsVisible.toString() != "false") {
37
+ await this.page.getByTitle("Mark all read").getByRole("button").click();
38
+ await this.page.getByRole("button", { name: "MARK ALL" }).click();
39
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
40
+ await expect(this.page.getByText("No records to display")).toBeVisible();
41
+ }
42
+ }
43
+ async selectAllNotifications() {
44
+ await this.page.getByRole("checkbox").first().click();
45
+ }
46
+ async selectNotification(nth = 1) {
47
+ await this.page.getByRole("checkbox").nth(nth).click();
48
+ }
49
+ async selectSeverity(severity = "") {
50
+ await this.page.getByLabel("Severity").click();
51
+ await this.page.getByRole("option", { name: severity }).click();
52
+ await expect(this.page.getByRole("table").filter({ hasText: "Rows per page" })).toBeVisible();
53
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
54
+ }
55
+ async saveSelected() {
56
+ await this.page
57
+ .locator("thead")
58
+ .getByTitle("Save selected for later")
59
+ .getByRole("button")
60
+ .click();
61
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
62
+ }
63
+ async saveAllSelected() {
64
+ await this.page
65
+ .locator("thead")
66
+ .getByTitle("Save selected for later")
67
+ .getByRole("button")
68
+ .click();
69
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
70
+ }
71
+ async viewSaved() {
72
+ await this.page.getByLabel("View").click();
73
+ await this.page.getByRole("option", { name: "Saved" }).click();
74
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
75
+ }
76
+ async markLastNotificationAsRead() {
77
+ const row = this.page.locator("td:nth-child(3) > div").first();
78
+ await row.getByRole("button").nth(1).click();
79
+ }
80
+ async markNotificationAsRead(text) {
81
+ const row = this.page.locator(`tr:has-text("${text}")`);
82
+ await row.getByRole("button").nth(1).click();
83
+ }
84
+ async markLastNotificationAsUnRead() {
85
+ const row = this.page.locator("td:nth-child(3) > div").first();
86
+ await row.getByRole("button").nth(1).click();
87
+ }
88
+ async viewRead() {
89
+ await this.page.getByLabel("View").click();
90
+ await this.page
91
+ .getByRole("option", { name: "Read notifications", exact: true })
92
+ .click();
93
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
94
+ }
95
+ async viewUnRead() {
96
+ await this.page.getByLabel("View").click();
97
+ await this.page
98
+ .getByRole("option", { name: "Unread notifications", exact: true })
99
+ .click();
100
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
101
+ }
102
+ async sortByOldestOnTop() {
103
+ await this.page.getByLabel("Sort by").click();
104
+ await this.page.getByRole("option", { name: "Oldest on top" }).click();
105
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
106
+ }
107
+ async sortByNewestOnTop() {
108
+ await this.page.getByLabel("Sort by").click();
109
+ await this.page.getByRole("option", { name: "Newest on top" }).click();
110
+ await expect(this.page.getByTestId("loading-indicator").getByRole("img")).toHaveCount(0);
111
+ }
112
+ }
@@ -0,0 +1,3 @@
1
+ import { $ } from "zx";
2
+ export { $ };
3
+ //# sourceMappingURL=bash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/utils/bash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,IAAI,CAAC;AAKvB,OAAO,EAAE,CAAC,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { $ } from "zx";
2
+ $.quiet = true;
3
+ $.stdio = ["inherit", "inherit", "inherit"];
4
+ export { $ };
@@ -0,0 +1,3 @@
1
+ declare function envsubst(str: string, env?: NodeJS.ProcessEnv): string;
2
+ export { envsubst };
3
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/utils/common.ts"],"names":[],"mappings":"AAAA,iBAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,oBAAc,UAS/C;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ function envsubst(str, env = process.env) {
2
+ const out = str.replace(/\$([A-Za-z_]\w*)|\$\{([A-Za-z_]\w*)(?::-(.*?))?\}/g, (_, v1, v2, def) => {
3
+ const k = v1 || v2;
4
+ return env[k] ?? (def !== undefined ? def : "");
5
+ });
6
+ return out;
7
+ }
8
+ export { envsubst };
@@ -0,0 +1,5 @@
1
+ export { envsubst } from "./common.js";
2
+ export { $ } from "./bash.js";
3
+ export { mergeYamlFiles, mergeYamlFilesIfExists, mergeYamlFilesToFile, } from "./merge-yamls.js";
4
+ export { KubernetesClientHelper } from "./kubernetes-client.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,CAAC,EAAE,MAAM,WAAW,CAAC;AAC9B,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { envsubst } from "./common.js";
2
+ export { $ } from "./bash.js";
3
+ export { mergeYamlFiles, mergeYamlFilesIfExists, mergeYamlFilesToFile, } from "./merge-yamls.js";
4
+ export { KubernetesClientHelper } from "./kubernetes-client.js";
@@ -0,0 +1,97 @@
1
+ import * as k8s from "@kubernetes/client-node";
2
+ /**
3
+ * Kubernetes client wrapper with proper abstraction
4
+ */
5
+ declare class KubernetesClientHelper {
6
+ private _kc;
7
+ private _k8sApi;
8
+ private _appsApi;
9
+ private _customObjectsApi;
10
+ constructor();
11
+ /**
12
+ * Create or update a ConfigMap from a file
13
+ */
14
+ createOrUpdateConfigMap(name: string, namespace: string, configFilePath: string, dataKey?: string): Promise<k8s.V1ConfigMap>;
15
+ /**
16
+ * Create a namespace if it doesn't exist
17
+ */
18
+ createNamespaceIfNotExists(namespace: string): Promise<k8s.V1Namespace>;
19
+ /**
20
+ * Apply a Kubernetes manifest from a YAML file
21
+ // */
22
+ /**
23
+ * Apply a Kubernetes resource dynamically
24
+ */
25
+ /**
26
+ * Create or update a Secret
27
+ */
28
+ private _applySecret;
29
+ /**
30
+ * Create or update a ConfigMap from a plain object
31
+ */
32
+ applyConfigMapFromObject(name: string, data: Record<string, unknown>, namespace: string): Promise<void>;
33
+ /**
34
+ * Create or update a Secret from a plain object
35
+ */
36
+ applySecretFromObject(name: string, data: {
37
+ stringData?: Record<string, string>;
38
+ }, namespace: string): Promise<void>;
39
+ /**
40
+ * Delete a namespace and wait for it to be fully terminated
41
+ */
42
+ deleteNamespace(namespace: string, waitForDeletion?: boolean, timeoutSeconds?: number): Promise<void>;
43
+ /**
44
+ * Wait for a namespace to be fully deleted
45
+ */
46
+ private _waitForNamespaceDeletion;
47
+ /**
48
+ * Check if an error is a "not found" (404) error.
49
+ * Handles different error formats from various k8s client versions.
50
+ */
51
+ private _isNotFoundError;
52
+ /**
53
+ * Check if a StatefulSet is ready (all replicas are available)
54
+ */
55
+ isStatefulSetReady(namespace: string, name: string): Promise<boolean>;
56
+ /**
57
+ * Wait for a StatefulSet to be ready (all replicas available)
58
+ */
59
+ waitForStatefulSetReady(namespace: string, name: string, timeoutSeconds?: number, pollIntervalMs?: number): Promise<boolean>;
60
+ /**
61
+ * Get the cluster's ingress domain from OpenShift config
62
+ * Equivalent to: oc get ingresses.config.openshift.io cluster -o jsonpath='{.spec.domain}'
63
+ */
64
+ getClusterIngressDomain(): Promise<string>;
65
+ /**
66
+ * Get the URL/location of an OpenShift Route by name
67
+ *
68
+ * @param namespace - The namespace to search in
69
+ * @param name - The route name
70
+ * @returns The route URL (e.g., https://myapp.apps.cluster.example.com)
71
+ */
72
+ getRouteLocation(namespace: string, name: string): Promise<string>;
73
+ /**
74
+ * Extract the URL from a route object
75
+ */
76
+ private _extractRouteUrl;
77
+ /**
78
+ * Failure states that indicate a pod will not recover without intervention
79
+ */
80
+ private static readonly failureReasons;
81
+ /**
82
+ * Wait for pods matching a label selector to be ready, with early failure detection.
83
+ * Fails fast when it detects unrecoverable states like CrashLoopBackOff.
84
+ *
85
+ * @param namespace - Namespace to watch
86
+ * @param labelSelector - Label selector (e.g., "app=myapp")
87
+ * @param timeoutSeconds - Maximum time to wait (default: 300)
88
+ * @param pollIntervalMs - How often to check pod status (default: 5000)
89
+ */
90
+ waitForPodsWithFailureDetection(namespace: string, labelSelector: string, timeoutSeconds?: number, pollIntervalMs?: number): Promise<void>;
91
+ /**
92
+ * Check if a pod is in a failure state. Returns failure info or null if healthy.
93
+ */
94
+ private _checkPodFailure;
95
+ }
96
+ export { KubernetesClientHelper };
97
+ //# sourceMappingURL=kubernetes-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kubernetes-client.d.ts","sourceRoot":"","sources":["../../src/utils/kubernetes-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,GAAG,MAAM,yBAAyB,CAAC;AAO/C;;GAEG;AACH,cAAM,sBAAsB;IAC1B,OAAO,CAAC,GAAG,CAAiB;IAC5B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,iBAAiB,CAAuB;;IAoChD;;OAEG;IACG,uBAAuB,CAC3B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IA8C3B;;OAEG;IACG,0BAA0B,CAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IA+B3B;;UAEM;IAmBN;;OAEG;IAsBH;;OAEG;YACW,YAAY;IA8B1B;;OAEG;IACG,wBAAwB,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IA0ChB;;OAEG;IACG,qBAAqB,CACzB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAC7C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAqChB;;OAEG;IACG,eAAe,CACnB,SAAS,EAAE,MAAM,EACjB,eAAe,GAAE,OAAc,EAC/B,cAAc,GAAE,MAAY,GAC3B,OAAO,CAAC,IAAI,CAAC;IAyBhB;;OAEG;YACW,yBAAyB;IAsCvC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA2BxB;;OAEG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc3E;;OAEG;IACG,uBAAuB,CAC3B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,cAAc,GAAE,MAAY,EAC5B,cAAc,GAAE,MAAa,GAC5B,OAAO,CAAC,OAAO,CAAC;IAiBnB;;;OAGG;IACG,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC;IAsBhD;;;;;;OAMG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAkBxE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAmBxB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAQnC;IAEH;;;;;;;;OAQG;IACG,+BAA+B,CACnC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,cAAc,GAAE,MAAY,EAC5B,cAAc,GAAE,MAAa,GAC5B,OAAO,CAAC,IAAI,CAAC;IA8FhB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CA8BzB;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}