diff --git a/workspaces/backstage/e2e-tests/playwright.config.ts b/workspaces/backstage/e2e-tests/playwright.config.ts index 643d7f59a..0a7d19d5e 100644 --- a/workspaces/backstage/e2e-tests/playwright.config.ts +++ b/workspaces/backstage/e2e-tests/playwright.config.ts @@ -9,6 +9,10 @@ dotenv.config({ path: `${import.meta.dirname}/.env` }); */ export default defineConfig({ projects: [ + { + name: "backstage-github-discovery", + testMatch: /tests\/specs\/github-discovery\.spec\.ts/, + }, { name: "backstage-gitlab-discovery", testMatch: /tests\/specs\/gitlab-discovery\.spec\.ts/, diff --git a/workspaces/backstage/e2e-tests/support/api/api-helper.ts b/workspaces/backstage/e2e-tests/support/api/api-helper.ts deleted file mode 100644 index c71404d2f..000000000 --- a/workspaces/backstage/e2e-tests/support/api/api-helper.ts +++ /dev/null @@ -1,366 +0,0 @@ -import { request } from "@playwright/test"; -/** - * Helper class for making API calls to GitHub and RHDH - */ -export class CustomAPIHelper { - /** - * Get a group entity from the RHDH catalog API - */ - static async getGroupEntityFromAPI( - baseUrl: string, - token: string, - groupName: string, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ): Promise { - const context = await request.newContext({ - ignoreHTTPSErrors: true, - }); - - const url = `${baseUrl}/api/catalog/entities/by-name/group/default/${groupName}`; - const response = await context.get(url, { - headers: { - Authorization: `Bearer ${token}`, - }, - }); - if (!response.ok()) { - throw new Error( - `Failed to get group entity: ${response.status()} ${response.statusText()}`, - ); - } - - return await response.json(); - } - - /** - * Extract group members from a group entity - */ - static async getGroupMembers( - baseUrl: string, - token: string, - groupName: string, - ): Promise { - const groupEntity = await CustomAPIHelper.getGroupEntityFromAPI( - baseUrl, - token, - groupName, - ); - const members = - groupEntity.relations - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ?.filter((r: any) => r.type === "hasMember") - // eslint-disable-next-line @typescript-eslint/no-explicit-any - .map((r: any) => r.targetRef.split("/")[1]) || []; - return members; - } - - /** - * Create a GitHub repository with a file - */ - static async createGitHubRepoWithFile( - owner: string, - repo: string, - filePath: string, - content: string, - token: string, - ): Promise { - const createRepoResponse = await fetch( - `https://api.github.com/orgs/${owner}/repos`, - { - method: "POST", - headers: { - Authorization: `token ${token}`, - "Content-Type": "application/json", - Accept: "application/vnd.github+json", - }, - body: JSON.stringify({ - name: repo, - private: false, - // eslint-disable-next-line @typescript-eslint/naming-convention - auto_init: true, - }), - }, - ); - - if (!createRepoResponse.ok) { - const errorText = await createRepoResponse.text(); - throw new Error( - `Failed to create repository: ${createRepoResponse.status} ${errorText}`, - ); - } - - await new Promise((resolve) => setTimeout(resolve, 2000)); - - const createFileResponse = await fetch( - `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`, - { - method: "PUT", - headers: { - Authorization: `token ${token}`, - "Content-Type": "application/json", - Accept: "application/vnd.github+json", - }, - body: JSON.stringify({ - message: `Add ${filePath}`, - content: Buffer.from(content).toString("base64"), - }), - }, - ); - - if (!createFileResponse.ok) { - const errorText = await createFileResponse.text(); - throw new Error( - `Failed to create file: ${createFileResponse.status} ${errorText}`, - ); - } - } - - /** - * Update a file in a GitHub repository - */ - static async updateFileInRepo( - owner: string, - repo: string, - filePath: string, - content: string, - commitMessage: string, - token: string, - ): Promise { - const getFileResponse = await fetch( - `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`, - { - headers: { - Authorization: `token ${token}`, - Accept: "application/vnd.github+json", - }, - }, - ); - - if (!getFileResponse.ok) { - throw new Error( - `Failed to get file: ${getFileResponse.status} ${getFileResponse.statusText}`, - ); - } - - const fileData = (await getFileResponse.json()) as { sha: string }; - - const updateFileResponse = await fetch( - `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`, - { - method: "PUT", - headers: { - Authorization: `token ${token}`, - "Content-Type": "application/json", - Accept: "application/vnd.github+json", - }, - body: JSON.stringify({ - message: commitMessage, - content: Buffer.from(content).toString("base64"), - sha: fileData.sha, - }), - }, - ); - - if (!updateFileResponse.ok) { - const errorText = await updateFileResponse.text(); - throw new Error( - `Failed to update file: ${updateFileResponse.status} ${errorText}`, - ); - } - } - - /** - * Delete a file from a GitHub repository - */ - static async deleteFileInRepo( - owner: string, - repo: string, - filePath: string, - commitMessage: string, - token: string, - ): Promise { - const getFileResponse = await fetch( - `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`, - { - headers: { - Authorization: `token ${token}`, - Accept: "application/vnd.github+json", - }, - }, - ); - - if (getFileResponse.status === 404) { - console.log(`File ${filePath} already deleted or doesn't exist`); - return; - } - - if (!getFileResponse.ok) { - throw new Error( - `Failed to get file: ${getFileResponse.status} ${getFileResponse.statusText}`, - ); - } - - const fileData = (await getFileResponse.json()) as { sha: string }; - - const deleteFileResponse = await fetch( - `https://api.github.com/repos/${owner}/${repo}/contents/${filePath}`, - { - method: "DELETE", - headers: { - Authorization: `token ${token}`, - "Content-Type": "application/json", - Accept: "application/vnd.github+json", - }, - body: JSON.stringify({ - message: commitMessage, - sha: fileData.sha, - }), - }, - ); - - if (!deleteFileResponse.ok && deleteFileResponse.status !== 404) { - const errorText = await deleteFileResponse.text(); - throw new Error( - `Failed to delete file: ${deleteFileResponse.status} ${errorText}`, - ); - } - } - - /** - * Delete a GitHub repository - */ - static async deleteRepo( - owner: string, - repo: string, - token: string, - ): Promise { - const response = await fetch( - `https://api.github.com/repos/${owner}/${repo}`, - { - method: "DELETE", - headers: { - Authorization: `token ${token}`, - Accept: "application/vnd.github+json", - }, - }, - ); - - if (!response.ok && response.status !== 404) { - const errorText = await response.text(); - throw new Error( - `Failed to delete repository: ${response.status} ${errorText}`, - ); - } - } - - /** - * Create a team in a GitHub organization - */ - static async createTeamInOrg( - org: string, - teamName: string, - token: string, - ): Promise { - const response = await fetch(`https://api.github.com/orgs/${org}/teams`, { - method: "POST", - headers: { - Authorization: `token ${token}`, - "Content-Type": "application/json", - Accept: "application/vnd.github+json", - }, - body: JSON.stringify({ - name: teamName, - privacy: "closed", - }), - }); - - if (!response.ok) { - const errorText = await response.text(); - throw new Error(`Failed to create team: ${response.status} ${errorText}`); - } - } - - /** - * Delete a team from a GitHub organization - */ - static async deleteTeamFromOrg( - org: string, - teamName: string, - token: string, - ): Promise { - const response = await fetch( - `https://api.github.com/orgs/${org}/teams/${teamName}`, - { - method: "DELETE", - headers: { - Authorization: `token ${token}`, - Accept: "application/vnd.github+json", - }, - }, - ); - - if (!response.ok && response.status !== 404) { - const errorText = await response.text(); - throw new Error(`Failed to delete team: ${response.status} ${errorText}`); - } - } - - /** - * Add a user to a team in a GitHub organization - */ - static async addUserToTeam( - org: string, - teamName: string, - username: string, - token: string, - ): Promise { - const response = await fetch( - `https://api.github.com/orgs/${org}/teams/${teamName}/memberships/${username}`, - { - method: "PUT", - headers: { - Authorization: `token ${token}`, - "Content-Type": "application/json", - Accept: "application/vnd.github+json", - }, - body: JSON.stringify({ - role: "member", - }), - }, - ); - - if (!response.ok) { - const errorText = await response.text(); - throw new Error( - `Failed to add user to team: ${response.status} ${errorText}`, - ); - } - } - - /** - * Remove a user from a team in a GitHub organization - */ - static async removeUserFromTeam( - org: string, - teamName: string, - username: string, - token: string, - ): Promise { - const response = await fetch( - `https://api.github.com/orgs/${org}/teams/${teamName}/memberships/${username}`, - { - method: "DELETE", - headers: { - Authorization: `token ${token}`, - Accept: "application/vnd.github+json", - }, - }, - ); - - if (!response.ok && response.status !== 404) { - const errorText = await response.text(); - throw new Error( - `Failed to remove user from team: ${response.status} ${errorText}`, - ); - } - } -} diff --git a/workspaces/backstage/e2e-tests/support/api/catalog-api-helper.ts b/workspaces/backstage/e2e-tests/support/api/catalog-api-helper.ts new file mode 100644 index 000000000..5d1a92bee --- /dev/null +++ b/workspaces/backstage/e2e-tests/support/api/catalog-api-helper.ts @@ -0,0 +1,55 @@ +import { request } from "@playwright/test"; +/** + * Helper class for making API calls to Catalog + */ +export class CatalogApiHelper { + /** + * Get a group entity from the RHDH catalog API + */ + static async getGroupEntity( + baseUrl: string, + token: string, + groupName: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ): Promise { + const context = await request.newContext({ + ignoreHTTPSErrors: true, + }); + + const url = `${baseUrl}/api/catalog/entities/by-name/group/default/${groupName}`; + const response = await context.get(url, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + if (!response.ok()) { + throw new Error( + `Failed to get group entity: ${response.status()} ${response.statusText()}`, + ); + } + + return await response.json(); + } + + /** + * Extract group members from a group entity + */ + static async getGroupMembers( + baseUrl: string, + token: string, + groupName: string, + ): Promise { + const groupEntity = await CatalogApiHelper.getGroupEntity( + baseUrl, + token, + groupName, + ); + const members = + groupEntity.relations + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ?.filter((r: any) => r.type === "hasMember") + // eslint-disable-next-line @typescript-eslint/no-explicit-any + .map((r: any) => r.targetRef.split("/")[1]) || []; + return members; + } +} diff --git a/workspaces/backstage/e2e-tests/support/api/github-api-helper.ts b/workspaces/backstage/e2e-tests/support/api/github-api-helper.ts new file mode 100644 index 000000000..5f348c0fb --- /dev/null +++ b/workspaces/backstage/e2e-tests/support/api/github-api-helper.ts @@ -0,0 +1,183 @@ +import { APIResponse } from "@playwright/test"; +import { RHDH_GITHUB_TEST_ORGANIZATION } from "../constants/github/organization.js"; +import { + APIHelper, + GITHUB_API_ENDPOINTS, +} from "@red-hat-developer-hub/e2e-test-utils/helpers"; + +// https://docs.github.com/en/rest?apiVersion=2022-11-28 +export class GitHubApiHelper extends APIHelper { + static async safeGithubRequest( + method: string, + url: string, + body?: string | object, + ): Promise { + const response = await this.githubRequest(method, url, body); + if (!response.ok) { + throw new Error( + `Failed to ${method} ${url}: ${response.status()} ${response.statusText()}`, + ); + } + + return response; + } + + /** + * Update a file in a GitHub repository + */ + static async updateFileInRepo( + owner: string, + repo: string, + filePath: string, + content: string, + commitMessage: string, + ): Promise { + const getFileResponse = await this.safeGithubRequest( + "GET", + `${GITHUB_API_ENDPOINTS.contents(owner, repo)}/${filePath}`, + ); + + const fileData = (await getFileResponse.json()) as { sha: string }; + + await this.safeGithubRequest( + "PUT", + `${GITHUB_API_ENDPOINTS.contents(owner, repo)}/${filePath}`, + JSON.stringify({ + message: commitMessage, + content: Buffer.from(content).toString("base64"), + sha: fileData.sha, + }), + ); + } + + /** + * Delete a file from a GitHub repository + */ + static async deleteFileInRepo( + owner: string, + repo: string, + filePath: string, + commitMessage: string, + ): Promise { + const getFileResponse = await this.githubRequest( + "GET", + `${GITHUB_API_ENDPOINTS.contents(owner, repo)}/${filePath}`, + ); + if (getFileResponse.status() === 404) { + console.log(`File ${filePath} already deleted or doesn't exist`); + return; + } + if (!getFileResponse.ok) { + throw new Error( + `Failed to get file: ${getFileResponse.status()} ${getFileResponse.statusText()}`, + ); + } + + const fileData = (await getFileResponse.json()) as { sha: string }; + + await this.safeGithubRequest( + "DELETE", + `${GITHUB_API_ENDPOINTS.contents(owner, repo)}/${filePath}`, + JSON.stringify({ + message: commitMessage, + sha: fileData.sha, + }), + ); + } + + /** + * Create a team in a GitHub organization + */ + static async createTeamInOrg(org: string, teamName: string): Promise { + await this.safeGithubRequest( + "POST", + `${GITHUB_API_ENDPOINTS.getOrg(org)}/teams`, + JSON.stringify({ + name: teamName, + privacy: "closed", + }), + ); + } + + /** + * Delete a team from a GitHub organization + */ + static async deleteTeamFromOrg(org: string, teamName: string): Promise { + const response = await this.githubRequest( + "DELETE", + `${GITHUB_API_ENDPOINTS.getOrg(org)}/teams/${teamName}`, + ); + + if (!response.ok && response.status() !== 404) { + throw new Error( + `Failed to delete team: ${response.status()} ${response.statusText()}`, + ); + } + } + + /** + * Add a user to a team in a GitHub organization + */ + static async addUserToTeam( + org: string, + teamName: string, + username: string, + ): Promise { + await this.safeGithubRequest( + "PUT", + `${GITHUB_API_ENDPOINTS.getOrg(org)}/teams/${teamName}/memberships/${username}`, + JSON.stringify({ + role: "member", + }), + ); + } + + /** + * Remove a user from a team in a GitHub organization + */ + static async removeUserFromTeam( + org: string, + teamName: string, + username: string, + ): Promise { + const response = await this.githubRequest( + "DELETE", + `${GITHUB_API_ENDPOINTS.getOrg(org)}/teams/${teamName}/memberships/${username}`, + ); + + if (!response.ok && response.status() !== 404) { + throw new Error( + `Failed to remove user from team: ${response.status()} ${response.statusText()}`, + ); + } + } + + static async getOrganizationReposUrl( + org = RHDH_GITHUB_TEST_ORGANIZATION, + ): Promise { + const response = await this.safeGithubRequest( + "GET", + GITHUB_API_ENDPOINTS.getOrg(org), + ); + return (await response.json())["repos_url"]; + } + + static async getReposFromOrg(org = RHDH_GITHUB_TEST_ORGANIZATION) { + const reposUrl = await this.getOrganizationReposUrl(org); + // GitHub defaults to 30; use 100 to reduce API calls. + return this.getGithubPaginatedRequest(`${reposUrl}?per_page=100`); + } + + static async fileExistsInRepo( + owner: string, + repo: string, + filePath: string, + ): Promise { + const resp = await this.githubRequest( + "GET", + `${GITHUB_API_ENDPOINTS.contents(owner, repo)}/${filePath}`, + ); + const status = resp.status(); + return [200, 302, 304].includes(status); + } +} diff --git a/workspaces/backstage/e2e-tests/support/constants/github/organization.ts b/workspaces/backstage/e2e-tests/support/constants/github/organization.ts new file mode 100644 index 000000000..11946beda --- /dev/null +++ b/workspaces/backstage/e2e-tests/support/constants/github/organization.ts @@ -0,0 +1 @@ +export const RHDH_GITHUB_TEST_ORGANIZATION = "janus-qe"; diff --git a/workspaces/backstage/e2e-tests/support/utils/require-env.ts b/workspaces/backstage/e2e-tests/support/utils/require-env.ts deleted file mode 100644 index e232b28cb..000000000 --- a/workspaces/backstage/e2e-tests/support/utils/require-env.ts +++ /dev/null @@ -1,8 +0,0 @@ -export function requireEnv(...names: [string, ...string[]]): void { - for (const name of names) { - const value = process.env[name]; - if (!value) { - throw new Error(`${name} environment variable is required`); - } - } -} diff --git a/workspaces/backstage/e2e-tests/tests/config/github-discovery/app-config-rhdh.yaml b/workspaces/backstage/e2e-tests/tests/config/github-discovery/app-config-rhdh.yaml new file mode 100644 index 000000000..d14a247ca --- /dev/null +++ b/workspaces/backstage/e2e-tests/tests/config/github-discovery/app-config-rhdh.yaml @@ -0,0 +1,36 @@ +app: + title: RHDH Backstage Github Discovery Test Instance + +catalog: + rules: + - allow: + [ + Component, + API, + Resource, + System, + Domain, + Location, + Template, + User, + Group, + ] + providers: + github: + providerId: + organization: ${GITHUB_ORG} + schedule: + frequency: + hours: 24 + timeout: + minutes: 10 + +integrations: + github: + - host: github.com + apps: + - appId: ${VAULT_GITHUB_APP_APP_ID} + clientId: ${VAULT_GITHUB_APP_CLIENT_ID} + clientSecret: ${VAULT_GITHUB_APP_CLIENT_SECRET} + webhookSecret: ${VAULT_GITHUB_APP_WEBHOOK_SECRET} + privateKey: ${VAULT_GITHUB_APP_PRIVATE_KEY} diff --git a/workspaces/backstage/e2e-tests/tests/config/github-discovery/dynamic-plugins.yaml b/workspaces/backstage/e2e-tests/tests/config/github-discovery/dynamic-plugins.yaml new file mode 100644 index 000000000..5219a5721 --- /dev/null +++ b/workspaces/backstage/e2e-tests/tests/config/github-discovery/dynamic-plugins.yaml @@ -0,0 +1,3 @@ +plugins: + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-plugin-catalog-backend-module-github:bs_1.45.3__0.11.2 + disabled: false diff --git a/workspaces/backstage/e2e-tests/tests/config/github-discovery/rhdh-secrets.yaml b/workspaces/backstage/e2e-tests/tests/config/github-discovery/rhdh-secrets.yaml new file mode 100644 index 000000000..4e3267d1f --- /dev/null +++ b/workspaces/backstage/e2e-tests/tests/config/github-discovery/rhdh-secrets.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Secret +metadata: + name: rhdh-secrets +type: Opaque +stringData: + VAULT_GITHUB_APP_APP_ID: $VAULT_GITHUB_APP_APP_ID + VAULT_GITHUB_APP_CLIENT_ID: $VAULT_GITHUB_APP_CLIENT_ID + VAULT_GITHUB_APP_CLIENT_SECRET: $VAULT_GITHUB_APP_CLIENT_SECRET + VAULT_GITHUB_APP_WEBHOOK_SECRET: $VAULT_GITHUB_APP_WEBHOOK_SECRET + VAULT_GITHUB_APP_PRIVATE_KEY: $VAULT_GITHUB_APP_PRIVATE_KEY + VAULT_GITHUB_USER_TOKEN: $VAULT_GITHUB_USER_TOKEN + GITHUB_ORG: janus-qe diff --git a/workspaces/backstage/e2e-tests/tests/specs/github-discovery.spec.ts b/workspaces/backstage/e2e-tests/tests/specs/github-discovery.spec.ts new file mode 100644 index 000000000..ce7eae3e2 --- /dev/null +++ b/workspaces/backstage/e2e-tests/tests/specs/github-discovery.spec.ts @@ -0,0 +1,63 @@ +import { CatalogPage } from "@red-hat-developer-hub/e2e-test-utils/pages"; +import { expect, test } from "@red-hat-developer-hub/e2e-test-utils/test"; +import { GitHubApiHelper } from "../../support/api/github-api-helper"; +import { RHDH_GITHUB_TEST_ORGANIZATION } from "../../support/constants/github/organization"; + +test.describe("Github Discovery Catalog", () => { + let catalogPage: CatalogPage; + + test.beforeAll(async ({ rhdh }) => { + // Allow time for deployment + 1 min provider refresh delay + browser setup + test.setTimeout(10 * 60 * 1000); + + await rhdh.configure({ + auth: "guest", + appConfig: "tests/config/github-discovery/app-config-rhdh.yaml", + secrets: "tests/config/github-discovery/rhdh-secrets.yaml", + dynamicPlugins: "tests/config/github-discovery/dynamic-plugins.yaml", + }); + await rhdh.deploy(); + // Wait 1 minute for github provider to refresh entities before running tests + await new Promise((resolve) => setTimeout(resolve, 1 * 60 * 1000)); + }); + + test.beforeEach(async ({ loginHelper, page }) => { + await loginHelper.loginAsGuest(); + catalogPage = new CatalogPage(page); + await catalogPage.go(); + }); + + test(`Discover Organization's Catalog`, async () => { + const organizationRepos = await GitHubApiHelper.getReposFromOrg( + RHDH_GITHUB_TEST_ORGANIZATION, + ); + const reposNames: string[] = (organizationRepos as Array<{ name?: string }>) + .map((repo) => repo.name) + .filter((name): name is string => typeof name === "string") + // filter for subset of organization repositories where the repository name matches the entity name + .filter((name) => name.startsWith("test-annotator")) + .slice(0, 5); + + const reposWithCatalogInfo: string[] = ( + await Promise.all( + reposNames.map(async (repo) => + (await GitHubApiHelper.fileExistsInRepo( + RHDH_GITHUB_TEST_ORGANIZATION, + repo, + "catalog-info.yaml", + )) + ? repo + : null, + ), + ) + ).filter((repo): repo is string => typeof repo === "string"); + + expect(reposWithCatalogInfo.length).toBeGreaterThan(0); + + for (const repo of reposWithCatalogInfo) { + await catalogPage.search(repo); + const row = await catalogPage.tableRow(repo); + await expect(row).toBeVisible(); + } + }); +}); diff --git a/workspaces/backstage/e2e-tests/tests/specs/github-events-module.spec.ts b/workspaces/backstage/e2e-tests/tests/specs/github-events-module.spec.ts index 59fb1f1a7..703b22c6f 100644 --- a/workspaces/backstage/e2e-tests/tests/specs/github-events-module.spec.ts +++ b/workspaces/backstage/e2e-tests/tests/specs/github-events-module.spec.ts @@ -5,9 +5,10 @@ import { test, } from "@red-hat-developer-hub/e2e-test-utils/test"; import { createHmac } from "node:crypto"; -import { CustomAPIHelper } from "../../support/api/api-helper"; +import { CatalogApiHelper } from "../../support/api/catalog-api-helper"; import { GitHubEventsHelper } from "../../support/api/github-events"; -import { requireEnv } from "../../support/utils/require-env"; +import { requireEnv } from "@red-hat-developer-hub/e2e-test-utils/utils"; +import { GitHubApiHelper } from "../../support/api/github-api-helper"; test.describe("GitHub Events Module", () => { let githubEventsHelper: GitHubEventsHelper; @@ -15,10 +16,7 @@ test.describe("GitHub Events Module", () => { let rhdhBaseUrl: string; test.beforeAll(async ({ rhdh }) => { - requireEnv( - "VAULT_GITHUB_APP_WEBHOOK_SECRET", - "VAULT_GH_RHDH_QE_USER_TOKEN", - ); + requireEnv("VAULT_GITHUB_APP_WEBHOOK_SECRET"); await rhdh.configure({ auth: "keycloak", @@ -79,7 +77,7 @@ test.describe("GitHub Events Module", () => { await context.dispose(); }); - test.describe("GitHub Discovery", () => { + test.describe.serial("GitHub Discovery", () => { const catalogRepoName = `janus-test-github-events-test-${Date.now()}`; const catalogRepoDetails = { name: catalogRepoName, @@ -101,12 +99,11 @@ spec: lifecycle: unknown owner: user:default/janus-qe`; - await CustomAPIHelper.createGitHubRepoWithFile( + await GitHubApiHelper.createGitHubRepoWithFile( catalogRepoDetails.owner, catalogRepoDetails.name, "catalog-info.yaml", catalogInfoYamlContent, - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, ); await githubEventsHelper.sendPushEvent( @@ -147,13 +144,12 @@ spec: type: other lifecycle: unknown owner: user:default/janus-qe`; - await CustomAPIHelper.updateFileInRepo( + await GitHubApiHelper.updateFileInRepo( catalogRepoDetails.owner, catalogRepoDetails.name, "catalog-info.yaml", updatedCatalogInfoYaml, "Update catalog-info.yaml description", - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, ); await githubEventsHelper.sendPushEvent( `janus-qe/${catalogRepoName}`, @@ -183,12 +179,11 @@ spec: }); test("Deleting an entity from the catalog", async ({ page, uiHelper }) => { - await CustomAPIHelper.deleteFileInRepo( + await GitHubApiHelper.deleteFileInRepo( catalogRepoDetails.owner, catalogRepoDetails.name, "catalog-info.yaml", "Remove catalog-info.yaml", - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, ); await githubEventsHelper.sendPushEvent( `janus-qe/${catalogRepoName}`, @@ -216,10 +211,9 @@ spec: }); test.afterAll(async () => { - await CustomAPIHelper.deleteRepo( + await GitHubApiHelper.deleteGitHubRepo( catalogRepoDetails.owner, catalogRepoDetails.name, - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, ); }); }); @@ -230,11 +224,7 @@ spec: const teamName = "test-team-" + Date.now(); test("Adding a new group", async ({ page, uiHelper }) => { - await CustomAPIHelper.createTeamInOrg( - "janus-qe", - teamName, - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, - ); + await GitHubApiHelper.createTeamInOrg("janus-qe", teamName); await githubEventsHelper.sendTeamEvent("created", teamName, "janus-qe"); await expect @@ -258,11 +248,7 @@ spec: }); test("Deleting a group", async ({ page, uiHelper }) => { - await CustomAPIHelper.deleteTeamFromOrg( - "janus-qe", - teamName, - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, - ); + await GitHubApiHelper.deleteTeamFromOrg("janus-qe", teamName); await githubEventsHelper.sendTeamEvent("deleted", teamName, "janus-qe"); @@ -338,11 +324,7 @@ spec: teamName = "test-team-" + Date.now(); - await CustomAPIHelper.createTeamInOrg( - "janus-qe", - teamName, - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, - ); + await GitHubApiHelper.createTeamInOrg("janus-qe", teamName); teamCreated = true; await githubEventsHelper.sendTeamEvent("created", teamName, "janus-qe"); @@ -352,32 +334,22 @@ spec: test.afterEach(async () => { if (userAddedToTeam) { - await CustomAPIHelper.removeUserFromTeam( + await GitHubApiHelper.removeUserFromTeam( "janus-qe", teamName, "rhdh-qe", - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, ); userAddedToTeam = false; } if (teamCreated) { - await CustomAPIHelper.deleteTeamFromOrg( - "janus-qe", - teamName, - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, - ); + await GitHubApiHelper.deleteTeamFromOrg("janus-qe", teamName); teamCreated = false; } }); test("Adding a user to a group", async ({ uiHelper }) => { - await CustomAPIHelper.addUserToTeam( - "janus-qe", - teamName, - "rhdh-qe", - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, - ); + await GitHubApiHelper.addUserToTeam("janus-qe", teamName, "rhdh-qe"); userAddedToTeam = true; await githubEventsHelper.sendMembershipEvent( @@ -392,7 +364,7 @@ spec: await expect .poll( () => - CustomAPIHelper.getGroupMembers( + CatalogApiHelper.getGroupMembers( rhdhBaseUrl, staticToken, teamName, @@ -407,12 +379,7 @@ spec: }); test("Removing a user from a group", async ({ uiHelper }) => { - await CustomAPIHelper.addUserToTeam( - "janus-qe", - teamName, - "rhdh-qe", - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, - ); + await GitHubApiHelper.addUserToTeam("janus-qe", teamName, "rhdh-qe"); userAddedToTeam = true; await githubEventsHelper.sendMembershipEvent( @@ -425,7 +392,7 @@ spec: await expect .poll( () => - CustomAPIHelper.getGroupMembers( + CatalogApiHelper.getGroupMembers( rhdhBaseUrl, staticToken, teamName, @@ -438,11 +405,10 @@ spec: ) .toContain("rhdh-qe"); - await CustomAPIHelper.removeUserFromTeam( + await GitHubApiHelper.removeUserFromTeam( "janus-qe", teamName, "rhdh-qe", - process.env.VAULT_GH_RHDH_QE_USER_TOKEN!, ); userAddedToTeam = false; @@ -458,7 +424,7 @@ spec: await expect .poll( () => - CustomAPIHelper.getGroupMembers( + CatalogApiHelper.getGroupMembers( rhdhBaseUrl, staticToken, teamName, diff --git a/workspaces/backstage/e2e-tests/tests/specs/gitlab-discovery.spec.ts b/workspaces/backstage/e2e-tests/tests/specs/gitlab-discovery.spec.ts index 8a21a0d6c..c3e06b87c 100644 --- a/workspaces/backstage/e2e-tests/tests/specs/gitlab-discovery.spec.ts +++ b/workspaces/backstage/e2e-tests/tests/specs/gitlab-discovery.spec.ts @@ -1,5 +1,5 @@ import { expect, test } from "@red-hat-developer-hub/e2e-test-utils/test"; -import { requireEnv } from "../../support/utils/require-env"; +import { requireEnv } from "@red-hat-developer-hub/e2e-test-utils/utils"; test.describe("gitlab discovery UI tests", () => { test.beforeAll(async ({ rhdh }) => { diff --git a/workspaces/backstage/e2e-tests/tests/specs/kubernetes-rbac.spec.ts b/workspaces/backstage/e2e-tests/tests/specs/kubernetes-rbac.spec.ts index 914cd0e0a..693b6b0dc 100644 --- a/workspaces/backstage/e2e-tests/tests/specs/kubernetes-rbac.spec.ts +++ b/workspaces/backstage/e2e-tests/tests/specs/kubernetes-rbac.spec.ts @@ -1,10 +1,13 @@ +import { KeycloakHelper } from "@red-hat-developer-hub/e2e-test-utils/keycloak"; import { expect, test } from "@red-hat-developer-hub/e2e-test-utils/test"; -import { $, WorkspacePaths } from "@red-hat-developer-hub/e2e-test-utils/utils"; +import { + $, + WorkspacePaths, + requireEnv, +} from "@red-hat-developer-hub/e2e-test-utils/utils"; import { KUBERNETES_USERS } from "../../support/constants/kubernetes/users"; import { KubernetesPage } from "../../support/pages/kubernetes"; import { KUBERNETES_COMPONENTS } from "../../support/pages/kubernetes-po"; -import { KeycloakHelper } from "@red-hat-developer-hub/e2e-test-utils/keycloak"; -import { requireEnv } from "../../support/utils/require-env"; const $pipe = $({ stdio: "pipe" });