Skip to content

Commit

Permalink
[e2e][RHIDP-754] Github discovery UI test (#1625)
Browse files Browse the repository at this point in the history
* + Github discovery UI test

* minor fixes

* + setup on rbac job

* - axios + PW api requests

* + playwright fixtures

* fix security error

* fix config file

* fixing configmap

* fixing configmap

* minor fix

* ensure repo is a component

* fix fileExistsOnRepo call

* deleting github link validation,

* fixes and githubApi fixture

* replace env variable to playwrightConfig
  • Loading branch information
nilgaar authored Sep 30, 2024
1 parent 0d0fe09 commit 18b78de
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ data:
rules:
- allow: [User, Group]
providers:
github:
providerId:
organization: '${GITHUB_ORG}'
schedule:
frequency: { minutes: 30}
timeout: { minutes: 30}
githubOrg:
id: production
githubUrl: "${GITHUB_URL}"
Expand Down
48 changes: 48 additions & 0 deletions e2e-tests/playwright/e2e/github-discovery.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { test as base } from '@playwright/test';
import { Catalog } from '../support/pages/Catalog';
import GithubApi from '../support/api/github';
import { CATALOG_FILE, JANUS_QE_ORG } from '../utils/constants';
import { Common } from '../utils/Common';
import { assert } from 'console';

type GithubDiscoveryFixture = {
catalogPage: Catalog;
githubApi: GithubApi;
testOrganization: string;
};

const test = base.extend<GithubDiscoveryFixture>({
catalogPage: async ({ page }, use) => {
await new Common(page).loginAsGithubUser();
const catalog = new Catalog(page);
await catalog.go();
use(catalog);
},
githubApi: new GithubApi(),
testOrganization: JANUS_QE_ORG,
});

test.describe('Github Discovery Catalog', () => {
test(`Discover Organization's Catalog`, async ({
catalogPage,
githubApi,
testOrganization,
}) => {
const organizationRepos = await githubApi.getReposFromOrg(testOrganization);
const reposNames: string[] = organizationRepos.map(repo => repo['name']);
const realComponents: string[] = reposNames.filter(
async repo =>
await githubApi.fileExistsOnRepo(
`${testOrganization}/${repo}`,
CATALOG_FILE,
),
);

for (let i = 0; i != realComponents.length; i++) {
const repo = realComponents[i];
await catalogPage.search(repo);
const row = await catalogPage.tableRow(repo);
assert(await row.isVisible());
}
});
});
15 changes: 15 additions & 0 deletions e2e-tests/playwright/support/api/github-structures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export class getOrganizationResponse {
reposUrl: string;
constructor(response: any) {
enum OrganizationResponseAttributes {
ReposUrl = 'repos_url',
}
this.reposUrl = response[OrganizationResponseAttributes.ReposUrl];
}
}

export enum ItemStatus {
open = 'open',
closed = 'closed',
all = 'all',
}
71 changes: 71 additions & 0 deletions e2e-tests/playwright/support/api/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { getOrganizationResponse } from './github-structures';
import { JANUS_ORG } from '../../utils/constants';
import { APIResponse, request } from '@playwright/test';

// https://docs.github.com/en/rest?apiVersion=2022-11-28
export default class GithubApi {
private static API_URL = 'https://api.github.com';
private static API_VERSION = '2022-11-28';
private static AUTH_HEADER = {
Accept: 'application/vnd.github+json',
Authorization: `Bearer ${process.env.GH_RHDH_QE_USER_TOKEN}`,
'X-GitHub-Api-Version': GithubApi.API_VERSION,
};

public async getOrganization(
org = JANUS_ORG,
): Promise<getOrganizationResponse> {
const req = await this._organization(org).get();
return new getOrganizationResponse(req.json());
}

public async getReposFromOrg(org = JANUS_ORG) {
const req = await this._organization(org).repos();
return req.json();
}

public async fileExistsOnRepo(repo: string, file: string): Promise<boolean> {
const req = await this._repo(repo).getContent(file);
const status = req.status();
if (status == 403) {
throw Error('You don-t have permissions to see this path');
}
return [200, 302, 304].includes(status);
}

private _myContext = request.newContext({
baseURL: GithubApi.API_URL,
extraHTTPHeaders: GithubApi.AUTH_HEADER,
});

private _repo(repo: string) {
const url = `/repos/${repo}/`;
return {
getContent: async (path: string) => {
path = url + path;
const context = await this._myContext;
return context.get(path);
},
};
}

private _organization(organization: string) {
const url = '/orgs/';

return {
get: async (): Promise<APIResponse> => {
const path: string = url + organization;
const context = await this._myContext;
return context.get(path);
},

repos: async (): Promise<APIResponse> => {
const context = await this._myContext;
const organizationResponse = await new GithubApi()
._organization(organization)
.get();
return context.get((await organizationResponse.json()).repos_url);
},
};
}
}
24 changes: 23 additions & 1 deletion e2e-tests/playwright/support/pages/Catalog.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
import { Page } from '@playwright/test';
import { Locator, Page } from '@playwright/test';
import { UIhelper } from '../../utils/UIhelper';
import playwrightConfig from '../../../playwright.config';

//${BASE_URL}/catalog page
export class Catalog {
private page: Page;
private uiHelper: UIhelper;
private searchField: Locator;

constructor(page: Page) {
this.page = page;
this.uiHelper = new UIhelper(page);
this.searchField = page.locator('#input-with-icon-adornment');
}

async go() {
await this.uiHelper.openSidebar('Catalog');
}

async goToBackstageJanusProjectCITab() {
Expand All @@ -23,4 +30,19 @@ export class Catalog {
await this.uiHelper.clickByDataTestId('user-picker-all');
await this.uiHelper.clickLink('backstage-janus');
}

async search(s: string) {
await this.searchField.clear();
const searchResponse = this.page.waitForResponse(
new RegExp(
`${playwrightConfig.use.baseURL}/api/catalog/entities/by-query/*`,
),
);
await this.searchField.fill(s);
await searchResponse;
}

async tableRow(content: string) {
return this.page.locator(`tr >> a >> text="${content}"`);
}
}
20 changes: 20 additions & 0 deletions e2e-tests/playwright/support/pages/catalog-item.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, Page } from '@playwright/test';
import { GITHUB_URL } from '../../utils/constants';

export class CatalogItem {
private page: Page;

githubLink = (path: string): string => {
return `a[href*="${GITHUB_URL}${path}"]`;
};

constructor(page: Page) {
this.page = page;
}

async validateGithubLink(s: string) {
const url = this.githubLink(s);
const link = this.page.locator(url).first();
await expect(link).toBeVisible();
}
}
5 changes: 5 additions & 0 deletions e2e-tests/playwright/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const GITHUB_URL = 'https://github.com/';
export const JANUS_ORG = 'janus-idp';
export const JANUS_QE_ORG = 'janus-qe';
export const SHOWCASE_REPO = `${JANUS_ORG}/backstage-showcase`;
export const CATALOG_FILE = 'catalog-info.yaml';

0 comments on commit 18b78de

Please sign in to comment.