test: add installation component for new e2e test of Kind feature (#7976)

test: kind installation e2e test

Signed-off-by: Anton Misskii <amisskii@redhat.com>
This commit is contained in:
amisskii 2024-07-11 14:43:39 +02:00 committed by GitHub
parent b2f98d7192
commit e662fd64ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 136 additions and 1 deletions

View file

@ -92,6 +92,7 @@ jobs:
env:
PODMANDESKTOP_CI_BOT_TOKEN: ${{ secrets.PODMANDESKTOP_CI_BOT_TOKEN }}
TEST_PODMAN_MACHINE: 'true'
SKIP_KIND_INSTALL: 'true'
run: yarn test:e2e
- uses: actions/upload-artifact@v4

View file

@ -61,3 +61,4 @@ export * from './model/pages/settings-bar';
export * from './model/pages/settings-page';
export * from './model/pages/welcome-page';
export * from './model/workbench/navigation';
export * from './model/workbench/status-bar';

View file

@ -25,6 +25,7 @@ export class ResourcesPage extends SettingsPage {
readonly featuredProviderResources: Locator;
readonly podmanResources: Locator;
readonly composeResources: Locator;
readonly kindResources: Locator;
constructor(page: Page) {
super(page, 'Resources');
@ -32,5 +33,6 @@ export class ResourcesPage extends SettingsPage {
this.featuredProviderResources = this.content.getByRole('region', { name: 'Featured Provider Resources' });
this.podmanResources = this.featuredProviderResources.getByRole('region', { name: 'podman', exact: true });
this.composeResources = this.featuredProviderResources.getByRole('region', { name: 'Compose', exact: true });
this.kindResources = this.featuredProviderResources.getByRole('region', { name: 'kind', exact: true });
}
}

View file

@ -0,0 +1,40 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import type { Locator, Page } from '@playwright/test';
import { handleConfirmationDialog } from '../../utility/operations';
import { BasePage } from '../pages/base-page';
export class StatusBar extends BasePage {
readonly kindInstallationButton: Locator;
constructor(page: Page) {
super(page);
this.kindInstallationButton = this.page.getByTitle(
'Kind not found on your system, click to download and install it',
);
}
public async installKindCLI(): Promise<void> {
await this.kindInstallationButton.click();
await handleConfirmationDialog(this.page, 'Kind');
await handleConfirmationDialog(this.page, 'Kind');
await handleConfirmationDialog(this.page, 'Kind', true, 'OK');
}
}

View file

@ -0,0 +1,87 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
import { type Page } from '@playwright/test';
import { expect as playExpect } from '@playwright/test';
import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest';
import { ExtensionsPage } from '../model/pages/extensions-page';
import { ResourcesPage } from '../model/pages/resources-page';
import { WelcomePage } from '../model/pages/welcome-page';
import { NavigationBar } from '../model/workbench/navigation';
import { StatusBar } from '../model/workbench/status-bar';
import { PodmanDesktopRunner } from '../runner/podman-desktop-runner';
import type { RunnerTestContext } from '../testContext/runner-test-context';
import { waitForPodmanMachineStartup } from '../utility/wait';
let pdRunner: PodmanDesktopRunner;
let page: Page;
let navigationBar: NavigationBar;
let resourcesPage: ResourcesPage;
let statusBar: StatusBar;
const extensionLabel: string = 'podman-desktop.kind';
const skipKindInstallation = process.env.SKIP_KIND_INSTALL ? process.env.SKIP_KIND_INSTALL : false;
beforeAll(async () => {
pdRunner = new PodmanDesktopRunner();
page = await pdRunner.start();
pdRunner.setVideoAndTraceName('kind-e2e');
const welcomePage = new WelcomePage(page);
await welcomePage.handleWelcomePage(true);
await waitForPodmanMachineStartup(page);
navigationBar = new NavigationBar(page);
resourcesPage = new ResourcesPage(page);
statusBar = new StatusBar(page);
});
beforeEach<RunnerTestContext>(async ctx => {
ctx.pdRunner = pdRunner;
});
afterAll(async () => {
await pdRunner.close();
});
describe('Kind End-to-End Tests', async () => {
test.skipIf(skipKindInstallation)('Install Kind CLI', async () => {
await navigationBar.openSettings();
await playExpect(resourcesPage.kindResources).not.toBeVisible();
await statusBar.installKindCLI();
await playExpect(statusBar.kindInstallationButton).not.toBeVisible();
});
test('Verify that Kind CLI is installed', async () => {
await navigationBar.openSettings();
await playExpect(resourcesPage.kindResources).toBeVisible();
});
test('Kind extension lifecycle', async () => {
const extensionsPage = new ExtensionsPage(page);
await navigationBar.openExtensions();
const kindExtension = await extensionsPage.getInstalledExtension('Kind extension', extensionLabel);
await playExpect
.poll(async () => await extensionsPage.extensionIsInstalled(extensionLabel), { timeout: 10000 })
.toBeTruthy();
await playExpect(kindExtension.status).toHaveText('ACTIVE');
await kindExtension.disableExtension();
await navigationBar.openSettings();
await playExpect(resourcesPage.kindResources).not.toBeVisible();
await navigationBar.openExtensions();
await kindExtension.enableExtension();
await navigationBar.openSettings();
await playExpect(resourcesPage.kindResources).toBeVisible();
});
});

View file

@ -147,11 +147,15 @@ export async function handleConfirmationDialog(
page: Page,
dialogTitle = 'Confirmation',
confirm = true,
confirmationButton = 'Yes',
cancelButton = 'Cancel',
): Promise<void> {
// wait for dialog to appear using waitFor
const dialog = page.getByRole('dialog', { name: dialogTitle, exact: true });
await dialog.waitFor({ state: 'visible', timeout: 3000 });
const button = confirm ? dialog.getByRole('button', { name: 'Yes' }) : dialog.getByRole('button', { name: 'Cancel' });
const button = confirm
? dialog.getByRole('button', { name: confirmationButton })
: dialog.getByRole('button', { name: cancelButton });
await button.click();
}