Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
551c379
jest: add new entry into module name mapper
Starle21 Nov 24, 2025
de25016
clean: forgotten console.log in TagsFilter
Starle21 Jan 7, 2026
b622db2
move: StatusIcon and PackageCount under generic components
Starle21 Feb 17, 2026
2adedff
change: early return in EmptyTableState component
Starle21 Dec 7, 2025
4503af5
move: helpers for TemplateDetails into that folder
Starle21 Feb 17, 2026
450b6af
move: AddOrEditTemplate under features
Starle21 Feb 24, 2026
09f1044
extract: create and edit workflows
Starle21 Feb 17, 2026
52c68ac
extract: cancel modal behavior
Starle21 Feb 17, 2026
a35de2a
extract: choose step behavior
Starle21 Feb 17, 2026
4abe5af
extract: logic from DefineContentStep
Starle21 Feb 24, 2026
3cc2425
extract: logic from RedhatRepositoriesStep
Starle21 Feb 25, 2026
d3e7af8
extract: logic from CustomRepositoriesStep
Starle21 Mar 1, 2026
7621680
extract: logic from SetUpDateStep
Starle21 Feb 24, 2026
27e14bc
extract: logic from DetailStep
Starle21 Feb 25, 2026
3479c40
extract: logic from ReviewStep
Starle21 Feb 25, 2026
578352d
rename: AddOrEditTemplate -> TemplateModalBase
Starle21 Feb 25, 2026
2e4ba76
extract: defineContent logic from AddTemplateContext
Starle21 Feb 24, 2026
998e4a8
rename: templateHelpers -> repositoryURLs
Starle21 Feb 24, 2026
262fab8
change: data structure of repositoryURLs
Starle21 Feb 25, 2026
92ffb67
extract: edit use-case from AddTemplateContext
Starle21 Feb 24, 2026
5fc6073
extract: checkIsDisabledStep from AddTemplateContext
Starle21 Feb 11, 2026
ec7f361
extract: queryClient from AddTemplateContext
Starle21 Feb 24, 2026
3ab5c16
add: types for the workflow
Starle21 Feb 25, 2026
bd725a7
move: shared core functions into shared folder
Starle21 Feb 25, 2026
f7af956
change: storage in AddTemplateContext
Starle21 Mar 2, 2026
43e7a4e
add: temporary set state from old to new storage
Starle21 Feb 28, 2026
55e4887
add, change: checking isEmptyTemplateRequest in AddTemplateContext
Starle21 Mar 2, 2026
ab63b15
change: use new template store api in enableStep
Starle21 Feb 25, 2026
cb55886
change: use new template store api in createTemplate
Starle21 Feb 28, 2026
2f2d1d2
change: use new template store api in editTemplate confirm
Starle21 Feb 28, 2026
c26182c
change: use new template store api in reviewTemplateRequest
Starle21 Feb 19, 2026
76e0ece
change: use new template store api in describeTemplate
Starle21 Feb 24, 2026
36455e7
change: use new template store api in defineContent
Starle21 Feb 28, 2026
a75e938
change: use new template store api in selectSnapshots
Starle21 Mar 2, 2026
612b230
change: use new template store api in repositories selection
Starle21 Mar 2, 2026
dc33809
change: use new template store api in editTemplate initialize
Starle21 Feb 24, 2026
6af4411
delete: old template request store in AddTemplateContext
Starle21 Feb 23, 2026
37261ad
change: enableStep
Starle21 Feb 17, 2026
148003e
rename: AddTemplateContextProvider -> TemplateStore
Starle21 Feb 24, 2026
4355dad
change: AddOrEditTemplateModal
Starle21 Feb 17, 2026
8a54a0c
extract: createNewTemplate use-case
Starle21 Feb 28, 2026
298605e
extract: confirmEditTemplate and getTemplate use-cases
Starle21 Feb 28, 2026
f6fcdb1
extract, change: use-cases in DefineContent
Starle21 Feb 24, 2026
bf73c30
extract, change: use-case and UI in selectSnapshots
Starle21 Mar 1, 2026
86af607
extract: restrictFutureDates and props in SnapshotPicker
Starle21 Mar 1, 2026
ccbee4b
extract, change: formatTemplateReview, ReviewTemplateContent
Starle21 Feb 24, 2026
7dc0518
extract, change: validate use-cases in describeTemplate
Starle21 Feb 24, 2026
0457704
extract: sort repositories table
Starle21 Mar 1, 2026
3cc7f35
extract: toggleSelectedRepository in redhatRepositories
Starle21 Mar 1, 2026
417962c
extract, change: structure of RedhatRepositoriesStore
Starle21 Mar 2, 2026
f6eb6c9
extract: toggleOtherRepository in otherRepositories
Starle21 Mar 1, 2026
5656ad0
extract: refreshRepositories
Starle21 Mar 1, 2026
74c5f9b
extract, change: structure of CustomRepositoriesStore
Starle21 Mar 2, 2026
19e8a9d
documentation: notes for create template feature refactor
Starle21 Dec 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/playwright-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ jobs:
- name: Run testing proxy
run: docker run -d --network=host -e HTTPS_PROXY=$RH_PROXY_URL -e ROUTES_JSON_PATH=/config/routes-ci.json -v "$(pwd)/config:/config:ro,Z" --name frontend-development-proxy quay.io/redhat-user-workloads/hcc-platex-services-tenant/frontend-development-proxy:latest

- name: Setup the minimal needed repositories (Small RHEL, EPEL 10)
- name: Setup the initial needed repositories (Hardcoded RHEL, EPEL 10, SMALL)
working-directory: content-sources-backend
run: make repos-minimal

- name: Wait for setup repos to be valid
timeout-minutes: 3
timeout-minutes: 5
working-directory: content-sources-backend
run: while [[ "$(curl http://localhost:8000/api/content-sources/v1.0/repositories/ -H "$( ./scripts/header.sh 9999 1111)" | jq '.data | all(.status == "Valid")')" == "false" ]]; do sleep 5; done;

Expand Down
59 changes: 36 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ One can also: `yarn test` to run the unit tests directly.

## Testing with Playwright

There are 2 kinds of Playwright tests - UI tests and Itegration tests.

### First time running Playwright

Before running any of the Playwright tests for the first time:

1. Ensure the correct node version is installed and in use: `nvm use`

2. Copy the [example env file](playwright_example.env) and create a file named:`.env`
Expand All @@ -97,24 +103,47 @@ One can also: `yarn test` to run the unit tests directly.

`yarn playwright install --with-deps`

4. Run the backend locally, steps to do this can be found in the [backend repository](https://github.com/content-services/content-sources-backend).
### Running UI Playwright tests:

1. Run the backend locally, steps to do this can be found in the [backend repository](https://github.com/content-services/content-sources-backend).

Ensure that the backend is running prior to the following steps.

5. `yarn local` will start up the front-end repository. If you do `yarn start` and choose stage, your tests will attempt to run against the stage ENV, please do not test in stage.
2. make sure values in your `.env` file are:
1. `PROXY = ""`
2. `INTEGRATION=""`

6. `yarn playwright test` will run the playwright test suite. `yarn playwright test --headed` will run the suite in a vnc-like browser so you can watch it's interactions.
3. run `make repo-minimal` in the backend repository to import and snapshot the initial required RedHat repositories. Wait until all the repositories become `Valid`.

For tips and recommendations on how to write Playwright tests. Check out the Playwright [style guide](/_playwright-tests/style_guide.md) in this repo.
4. `yarn local` will start up the front-end repository. If you do `yarn start` and choose stage, your tests will attempt to run against the stage ENV, please do not test in stage.

It is recommended to test using vs-code and the [Playwright Test module for VSCode](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright). But other editors do have similar plugins to for ease of use, if so desired.
5. `yarn playwright test` will run the playwright test suite. `yarn playwright test --headed` will run the suite in a vnc-like browser so you can watch it's interactions.

### Running Integration Playwright tests with your frontend changes:

For running the integration tests you will need to point playwright to stage directly (i.e.: set proxy and change URL, check `playwright_example.env`), set the `INTEGRATION` flag to true and run the tests.
1. Point Playwright to stage directly in your `.env` file (check `playwright_example.env`):
1. set proxy: `http://squid.corp.redhat.com:3128`
2. change URL to: `https://stage.foo.redhat.com` to run against stage backend
2. set the `INTEGRATION` flag to `true` in your `.env`

3. For Podman, uncomment the DOCKER_SOCKET option in the `.env` file, so testing containers can reach out: `DOCKER_SOCKET="/tmp/podman.sock"`

4. For Podman to serve the API for client testing, enter the following into a terminal and let it run: `podman system service -t 0 unix:///tmp/podman.sock`

5. `yarn start:stage` to run your local frontend against stage

6. Run the tests

For running RBAC tests locally you just need to set the RBAC environment variable to `true`. See the `playwright_example.env` file for the `RBAC` flag.

For any other `.env` variables you might need consult our `aws account`.

To add new users, edit the `ALL_USERS` array in `_playwright-tests/auth.setup.ts`. To authenticate only specific users, set `AUTH_USERS=admin,readonly` (comma-separated keys).

For tips and recommendations on how to write Playwright tests. Check out the Playwright [style guide](/_playwright-tests/style_guide.md) in this repo.

It is recommended to test using vs-code and the [Playwright Test module for VSCode](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright). But other editors do have similar plugins to for ease of use, if so desired.

### Shared Playwright test utilities

This repo contains a `_playwright-tests/test-utils` git submodule which has a set of shared helpers and fixtures (and API client) across our Playwright testing suites.
Expand All @@ -137,23 +166,7 @@ _I am using the regular submodule setup. When working on new tests I thought of

</details>

## Running integration tests

## Podman

For podman to serve the API for client testing, enter:

```
podman system service -t 0 unix:///tmp/podman.sock
```

Uncomment the DOCKER_SOCKET option in the `.env file:

```
DOCKER_SOCKET="/tmp/podman.sock"
```

## PR checks and linking front-end/back-end PRs for testing
### PR checks and linking front-end/back-end PRs for testing

The CICD pipeline for playwright (both front-end and back-end) will check in the description of the front-end PRs for the following formatted text:
`#testwith https://github.com/content-services/content-sources-backend/pull/<PR NUMBER>`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ test.describe('Assign Template to System via UI', () => {
await nextButton.click();

await expect(page.getByText('Enter template details')).toBeVisible();
await page.getByPlaceholder('Enter name').fill(templateName);
await page.getByPlaceholder('Description').fill('Test template for system assignment');
await page.getByPlaceholder('Enter title').fill(templateName);
await page.getByPlaceholder('Enter detail').fill('Test template for system assignment');
await nextButton.click();

await page.getByRole('button', { name: 'Create template and add to systems' }).click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ test.describe('Associated Template CRUD', () => {
page.getByText('Enter template details'),
'should be on the Enter template details tab',
).toBeVisible();
await page.getByPlaceholder('Enter name').fill(`${templateName}`);
await page.getByPlaceholder('Description').fill('Template test for associated system CRUD');
await page.getByPlaceholder('Enter title').fill(`${templateName}`);
await page.getByPlaceholder('Enter detail').fill('Template test for associated system CRUD');
await page.getByRole('button', { name: 'Next', exact: true }).click();

await page.getByRole('button', { name: 'Create other options' }).click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ test.describe('Test System With Template', () => {
await page.getByPlaceholder('YYYY-MM-DD', { exact: true }).fill('2021-05-17'); // Older than any snapshot date
await page.getByRole('button', { name: 'Next', exact: true }).click();
await expect(page.getByText('Enter template details')).toBeVisible();
await page.getByPlaceholder('Enter name').fill(`${templateName}`);
await page.getByPlaceholder('Description').fill('Template test');
await page.getByPlaceholder('Enter title').fill(`${templateName}`);
await page.getByPlaceholder('Enter detail').fill('Template test');
await page.getByRole('button', { name: 'Next', exact: true }).click();
await page.getByRole('button', { name: 'Create other options' }).click();
await page.getByText('Create template only', { exact: true }).click();
Expand Down Expand Up @@ -126,9 +126,9 @@ test.describe('Test System With Template', () => {
await page.getByText('Use the latest content', { exact: true }).click();
await page.getByRole('button', { name: 'Next', exact: true }).click();
await expect(page.getByText('Enter template details')).toBeVisible();
await expect(page.getByPlaceholder('Enter name')).toHaveValue(`${templateName}`);
await expect(page.getByPlaceholder('Description')).toHaveValue('Template test');
await page.getByPlaceholder('Description').fill('Template test edited');
await expect(page.getByPlaceholder('Enter title')).toHaveValue(`${templateName}`);
await expect(page.getByPlaceholder('Enter detail')).toHaveValue('Template test');
await page.getByPlaceholder('Enter detail').fill('Template test edited');
await page.getByRole('button', { name: 'Next', exact: true }).click();
await page.getByRole('button', { name: 'Confirm changes', exact: true }).click();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ test.describe('Install Upload Repo Content', () => {
await page.getByText('Use the latest content', { exact: true }).click();
await page.getByRole('button', { name: 'Next', exact: true }).click();
await expect(page.getByText('Enter template details')).toBeVisible();
await page.getByPlaceholder('Enter name').fill(`${templateName}`);
await page.getByPlaceholder('Description').fill('Template test for upload repository');
await page.getByPlaceholder('Enter title').fill(`${templateName}`);
await page.getByPlaceholder('Enter detail').fill('Template test for upload repository');
await page.getByRole('button', { name: 'Next', exact: true }).click();
await page.getByRole('button', { name: 'Create other options' }).click();
await page.getByText('Create template only', { exact: true }).click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ test.describe('Register and assign template to systems via API', () => {
await page.getByRole('button', { name: 'Next', exact: true }).click();

await expect(page.getByText('Enter template details')).toBeVisible();
await page.getByPlaceholder('Enter name').fill(templateName);
await page.getByPlaceholder('Description').fill('Template for use template dialog test');
await page.getByPlaceholder('Enter title').fill(templateName);
await page.getByPlaceholder('Enter detail').fill('Template for use template dialog test');
await page.getByRole('button', { name: 'Next', exact: true }).click();

await page.getByRole('button', { name: 'Create other options' }).click();
Expand Down
8 changes: 4 additions & 4 deletions _playwright-tests/UI/RedHatRepo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { navigateToRepositories, navigateToSnapshotsOfRepository } from './helpe
import { closeGenericPopupsIfExist, waitForValidStatus } from './helpers/helpers';

test.describe('Red Hat Repositories', () => {
const smallRHRepo = 'Red Hat CodeReady Linux Builder for RHEL 9 ARM 64 (RPMs)';
const appstreamRHRepoName = 'Red Hat Enterprise Linux 10 for ARM 64 - AppStream (RPMs)';

test.beforeEach(async ({ page }) => {
await test.step('Navigate to repositories page', async () => {
Expand All @@ -18,14 +18,14 @@ test.describe('Red Hat Repositories', () => {

test('Verify snapshotting of Red Hat repositories', async ({ page }) => {
await test.step('Wait for status to be "Valid"', async () => {
await waitForValidStatus(page, smallRHRepo, 210_000);
await waitForValidStatus(page, appstreamRHRepoName, 210_000);
});

await test.step('Check repository snapshots', async () => {
const row = page.getByRole('row').filter({ hasText: smallRHRepo });
const row = page.getByRole('row').filter({ hasText: appstreamRHRepoName });
await navigateToSnapshotsOfRepository(page, row);
await expect(
page.getByTestId('snapshot_list_modal').filter({ hasText: smallRHRepo }),
page.getByTestId('snapshot_list_modal').filter({ hasText: appstreamRHRepoName }),
).toBeVisible();
});

Expand Down
18 changes: 11 additions & 7 deletions _playwright-tests/UI/SnapshotRepo.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ test.describe('Snapshot Repositories', () => {
});

test('Snapshot deletion', async ({ page, client, cleanup }) => {
const smallRHRepo = 'Red Hat CodeReady Linux Builder for RHEL 9 ARM 64 (RPMs)';
const repoNamePrefix = 'snapshot-deletion';
const repoName = `${repoNamePrefix}-${randomName()}`;
const templateName = `Test-template-for-snapshot-deletion-${randomName()}`;
Expand Down Expand Up @@ -161,33 +160,38 @@ test.describe('Snapshot Repositories', () => {

await test.step('Create a template', async () => {
await navigateToTemplates(page);

// step 1 - select repo version combination
await page.getByRole('button', { name: 'Create template' }).click();
await page.getByRole('button', { name: 'filter architecture' }).click();
await page.getByRole('menuitem', { name: 'aarch64' }).click();
await page.getByRole('button', { name: 'filter OS version' }).click();
await page.getByRole('menuitem', { name: 'el9' }).click();
await page.getByRole('menuitem', { name: 'el10' }).click();
await page.getByRole('button', { name: 'Next', exact: true }).click();

// step 2 - select additional repos - the hardcoded ones are already selected
// all other repositories are optional to select
const modalPage = page.getByTestId('add_template_modal');
const rowRHELRepo = await getRowByNameOrUrl(modalPage, smallRHRepo);
await rowRHELRepo.getByLabel('Select row').click();
// wait till next button is enabled
await page.getByRole('button', { name: 'Next', exact: true }).isEnabled();
await page.getByRole('button', { name: 'Next', exact: true }).click();

// step 3 - select other repos
await expect(page.getByTestId('custom_repositories_step')).toBeVisible();
const customRepo = await getRowByNameOrUrl(modalPage, repoName);
await customRepo.getByLabel('Select row').click();
await page.getByRole('button', { name: 'Next', exact: true }).click();

// step 4 - select snapshots
await expect(page.getByTestId('set_up_date')).toBeVisible();
await page.getByTestId('use-latest-snapshot-radio').click();
await page.getByRole('radio', { name: 'Use the latest content' }).check();
await page.getByRole('button', { name: 'Next' }).click();

await page.getByPlaceholder('Enter name').fill(`${templateName}`);
await page.getByPlaceholder('Description').fill('Template test');
await page.getByPlaceholder('Enter title').fill(`${templateName}`);
await page.getByPlaceholder('Enter detail').fill('Template test');
await page.getByRole('button', { name: 'Next', exact: true }).click();

// step 6 - create template
await page.getByRole('button', { name: 'Create other options' }).click();
await page.getByText('Create template only', { exact: true }).click();

Expand Down
Loading
Loading