mirror of
https://github.com/podman-desktop/podman-desktop
synced 2026-05-24 02:08:24 +00:00
chore(test): initial draft for podman machine tests (#8785)
* chore(test): initial draft for podman machine tests Signed-off-by: Vladimir Lazar <vlazar@redhat.com>
This commit is contained in:
parent
2c363e700c
commit
dcba187c9c
7 changed files with 204 additions and 11 deletions
|
|
@ -44,7 +44,7 @@
|
|||
"test:e2e:extension": "npm run test:e2e:build && npm run test:e2e:extension:run",
|
||||
"test:e2e:extension:run": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' -- npx playwright test tests/playwright/src/specs/extension-installation.spec.ts",
|
||||
"test:e2e:pw": "npm run test:e2e:build && npm run test:e2e:pw:run",
|
||||
"test:e2e:pw:run": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' -- npx playwright test tests/playwright/src/specs/pod-smoke.spec.ts",
|
||||
"test:e2e:pw:run": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' -- npx playwright test tests/playwright/src/specs/podman-machine-tests.spec.ts",
|
||||
"test:e2e:update": "npm run test:e2e:build && npm run test:e2e:update:run",
|
||||
"test:e2e:update:run": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' -- npx playwright test tests/playwright/src/specs/installation/ -g @update-install",
|
||||
"test:main": "vitest run -r packages/main --passWithNoTests --coverage",
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ export class PodmanMachineDetails extends ResourcesPage {
|
|||
readonly podmanMachineStopButton: Locator;
|
||||
readonly podmanMachineDeleteButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
constructor(page: Page, podmanMachineName: string) {
|
||||
super(page);
|
||||
this.podmanMachineName = this.getPage().getByRole('heading', { name: 'Podman Machine' });
|
||||
this.podmanMachineName = this.getPage().getByRole('heading', { name: podmanMachineName });
|
||||
this.podmanMachineStatus = this.getPage().getByLabel('Connection Status Label');
|
||||
this.podmanMachineConnectionActions = this.getPage().getByRole('group', { name: 'Connection Actions' });
|
||||
this.podmanMachineStartButton = this.podmanMachineConnectionActions.getByRole('button', {
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ export class PodmanOnboardingPage extends OnboardingPage {
|
|||
readonly podmanMachineStartAfterCreationCheckbox: Locator;
|
||||
readonly podmanMachineCreateButton: Locator;
|
||||
readonly podmanMachineShowLogsButton: Locator;
|
||||
readonly goBackButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
|
|
@ -41,7 +42,7 @@ export class PodmanOnboardingPage extends OnboardingPage {
|
|||
name: 'Autostart Podman engine when launching Podman Desktop',
|
||||
});
|
||||
this.createMachinePageTitle = this.onboardingComponent.getByLabel('title');
|
||||
this.podmanMachineConfiguration = this.mainPage.getByRole('form', { name: 'Properties Information' });
|
||||
this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' });
|
||||
this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' });
|
||||
this.podmanMachineCPUs = this.podmanMachineConfiguration.getByRole('slider', { name: 'CPU(s)' });
|
||||
this.podmanMachineMemory = this.podmanMachineConfiguration.getByRole('slider', { name: 'Memory' });
|
||||
|
|
@ -59,5 +60,6 @@ export class PodmanOnboardingPage extends OnboardingPage {
|
|||
});
|
||||
this.podmanMachineCreateButton = this.podmanMachineConfiguration.getByRole('button', { name: 'Create' });
|
||||
this.podmanMachineShowLogsButton = this.mainPage.getByRole('button', { name: 'Show Logs' });
|
||||
this.goBackButton = this.page.getByRole('button', { name: 'Go back to resources' });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,20 @@ export class ResourcesPage extends SettingsPage {
|
|||
}
|
||||
|
||||
public async resourceCardIsVisible(resourceLabel: string): Promise<boolean> {
|
||||
const resourceCard = this.content.getByRole('region', { name: resourceLabel });
|
||||
return (await resourceCard.count()) > 0;
|
||||
return (await this.resourceCardLocatorGenerator(resourceLabel).count()) > 0;
|
||||
}
|
||||
|
||||
public async goToCreateNewResourcePage(resourceLabel: string): Promise<void> {
|
||||
if (!(await this.resourceCardIsVisible(resourceLabel))) {
|
||||
throw new Error(`Resource card with label ${resourceLabel} is not available`);
|
||||
}
|
||||
|
||||
await this.resourceCardLocatorGenerator(resourceLabel)
|
||||
.getByRole('button', { name: `Create new ${resourceLabel}` })
|
||||
.click();
|
||||
}
|
||||
|
||||
private resourceCardLocatorGenerator(resourceLabel: string): Locator {
|
||||
return this.content.getByRole('region', { name: resourceLabel, exact: true });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ test.describe.serial('Podman Machine verification', () => {
|
|||
await playExpect(resourcesPodmanConnections.resourceElement).toBeVisible({ timeout: 20_000 });
|
||||
await playExpect(resourcesPodmanConnections.resourceElementDetailsButton).toBeVisible();
|
||||
await resourcesPodmanConnections.resourceElementDetailsButton.click();
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page);
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page, PODMAN_MACHINE_NAME);
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineConnectionActions).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStartButton).toBeVisible();
|
||||
|
|
@ -163,7 +163,7 @@ test.describe.serial('Podman Machine verification', () => {
|
|||
});
|
||||
|
||||
test('Podman machine operations - STOP', async ({ page }) => {
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page);
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page, PODMAN_MACHINE_NAME);
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING', { timeout: 50_000 });
|
||||
await playExpect(podmanMachineDetails.podmanMachineStopButton).toBeEnabled();
|
||||
await podmanMachineDetails.podmanMachineStopButton.click();
|
||||
|
|
@ -171,14 +171,14 @@ test.describe.serial('Podman Machine verification', () => {
|
|||
});
|
||||
|
||||
test('Podman machine operations - START', async ({ page }) => {
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page);
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page, PODMAN_MACHINE_NAME);
|
||||
await playExpect(podmanMachineDetails.podmanMachineStartButton).toBeEnabled();
|
||||
await podmanMachineDetails.podmanMachineStartButton.click();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING', { timeout: 50_000 });
|
||||
});
|
||||
|
||||
test('Podman machine operations - RESTART', async ({ page }) => {
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page);
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page, PODMAN_MACHINE_NAME);
|
||||
await playExpect(podmanMachineDetails.podmanMachineRestartButton).toBeEnabled();
|
||||
await podmanMachineDetails.podmanMachineRestartButton.click();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('OFF', { timeout: 50_000 });
|
||||
|
|
|
|||
178
tests/playwright/src/specs/podman-machine-tests.spec.ts
Normal file
178
tests/playwright/src/specs/podman-machine-tests.spec.ts
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/**********************************************************************
|
||||
* 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 * as os from 'node:os';
|
||||
|
||||
import type { Page } from '@playwright/test';
|
||||
|
||||
import { PodmanMachineDetails } from '../model/pages/podman-machine-details-page';
|
||||
import { PodmanOnboardingPage } from '../model/pages/podman-onboarding-page';
|
||||
import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page';
|
||||
import { ResourcesPage } from '../model/pages/resources-page';
|
||||
import { expect as playExpect, test } from '../utility/fixtures';
|
||||
import { deletePodmanMachine } from '../utility/operations';
|
||||
import { waitForPodmanMachineStartup } from '../utility/wait';
|
||||
|
||||
const DEFAULT_PODMAN_MACHINE = 'Podman Machine';
|
||||
const DEFAULT_PODMAN_MACHINE_VISIBLE = 'podman-machine-default';
|
||||
const ROOTLESS_PODMAN_MACHINE_VISIBLE = 'podman-machine-rootless';
|
||||
const ROOTLESS_PODMAN_MACHINE = 'Podman Machine rootless';
|
||||
const RESOURCE_NAME = 'podman';
|
||||
|
||||
test.skip(os.platform() === 'linux', 'Tests suite should not run on Linux platform');
|
||||
|
||||
test.beforeAll(async ({ runner, welcomePage, page }) => {
|
||||
runner.setVideoAndTraceName('podman-machine-tests');
|
||||
await welcomePage.handleWelcomePage(true);
|
||||
await waitForPodmanMachineStartup(page);
|
||||
});
|
||||
|
||||
test.afterAll(async ({ runner }) => {
|
||||
await runner.close();
|
||||
});
|
||||
|
||||
test.describe.serial(`Podman machine switching validation `, () => {
|
||||
test('Check data for available Podman Machine and stop machine', async ({ page, navigationBar }) => {
|
||||
const settingsBar = await navigationBar.openSettings();
|
||||
await settingsBar.resourcesTab.click();
|
||||
const resourcesPage = new ResourcesPage(page);
|
||||
await playExpect(resourcesPage.heading).toBeVisible();
|
||||
await playExpect.poll(async () => await resourcesPage.resourceCardIsVisible(RESOURCE_NAME)).toBeTruthy();
|
||||
const resourcesPodmanConnections = new ResourceConnectionCardPage(
|
||||
page,
|
||||
RESOURCE_NAME,
|
||||
DEFAULT_PODMAN_MACHINE_VISIBLE,
|
||||
);
|
||||
await playExpect(resourcesPodmanConnections.providerConnections).toBeVisible({ timeout: 10_000 });
|
||||
await playExpect(resourcesPodmanConnections.resourceElement).toBeVisible({ timeout: 20_000 });
|
||||
await playExpect(resourcesPodmanConnections.resourceElementDetailsButton).toBeVisible();
|
||||
await resourcesPodmanConnections.resourceElementDetailsButton.click();
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page, DEFAULT_PODMAN_MACHINE);
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineConnectionActions).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStartButton).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineRestartButton).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStopButton).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineDeleteButton).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING', { timeout: 50_000 });
|
||||
await playExpect(podmanMachineDetails.podmanMachineStopButton).toBeEnabled();
|
||||
await podmanMachineDetails.podmanMachineStopButton.click();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('OFF', { timeout: 50_000 });
|
||||
});
|
||||
|
||||
test('Create rootless podman machine', async ({ page, navigationBar }) => {
|
||||
test.setTimeout(120000);
|
||||
|
||||
const dashboard = await navigationBar.openDashboard();
|
||||
await playExpect(dashboard.heading).toBeVisible();
|
||||
const settingsBar = await navigationBar.openSettings();
|
||||
await settingsBar.resourcesTab.click();
|
||||
|
||||
const resourcesPage = new ResourcesPage(page);
|
||||
await playExpect(resourcesPage.heading).toBeVisible();
|
||||
await playExpect.poll(async () => await resourcesPage.resourceCardIsVisible(RESOURCE_NAME)).toBeTruthy();
|
||||
await resourcesPage.goToCreateNewResourcePage(RESOURCE_NAME);
|
||||
|
||||
const podmanMachineCreatePage = new PodmanOnboardingPage(page);
|
||||
await playExpect(podmanMachineCreatePage.podmanMachineName).toBeVisible();
|
||||
await podmanMachineCreatePage.podmanMachineName.clear();
|
||||
await podmanMachineCreatePage.podmanMachineName.fill(ROOTLESS_PODMAN_MACHINE_VISIBLE);
|
||||
|
||||
await playExpect(podmanMachineCreatePage.podmanMachineRootfulCheckbox).toBeChecked();
|
||||
await podmanMachineCreatePage.podmanMachineRootfulCheckbox.locator('..').click();
|
||||
await playExpect(podmanMachineCreatePage.podmanMachineRootfulCheckbox).not.toBeChecked();
|
||||
|
||||
await playExpect(podmanMachineCreatePage.podmanMachineStartAfterCreationCheckbox).toBeChecked();
|
||||
await podmanMachineCreatePage.podmanMachineStartAfterCreationCheckbox.locator('..').click();
|
||||
await playExpect(podmanMachineCreatePage.podmanMachineStartAfterCreationCheckbox).not.toBeChecked();
|
||||
|
||||
await podmanMachineCreatePage.podmanMachineCreateButton.click();
|
||||
await playExpect(podmanMachineCreatePage.goBackButton).toBeEnabled({ timeout: 100000 });
|
||||
await podmanMachineCreatePage.goBackButton.click();
|
||||
|
||||
await playExpect(resourcesPage.heading).toBeVisible();
|
||||
});
|
||||
|
||||
test('Switch to rootless podman machine', async ({ page }) => {
|
||||
const resourcesPodmanConnections = new ResourceConnectionCardPage(
|
||||
page,
|
||||
RESOURCE_NAME,
|
||||
ROOTLESS_PODMAN_MACHINE_VISIBLE,
|
||||
);
|
||||
|
||||
await playExpect(resourcesPodmanConnections.resourceElementDetailsButton).toBeVisible();
|
||||
await resourcesPodmanConnections.resourceElementDetailsButton.click();
|
||||
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page, ROOTLESS_PODMAN_MACHINE);
|
||||
await playExpect(podmanMachineDetails.podmanMachineName).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('OFF');
|
||||
|
||||
await playExpect(podmanMachineDetails.podmanMachineStartButton).toBeEnabled();
|
||||
await podmanMachineDetails.podmanMachineStartButton.click();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING', { timeout: 50_000 });
|
||||
|
||||
await handlePopupDialog(page, 'Yes');
|
||||
await handlePopupDialog(page, 'OK');
|
||||
});
|
||||
|
||||
test('Stop rootless podman machine', async ({ page }) => {
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page, ROOTLESS_PODMAN_MACHINE);
|
||||
await playExpect(podmanMachineDetails.podmanMachineName).toBeVisible();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING');
|
||||
await playExpect(podmanMachineDetails.podmanMachineStopButton).toBeEnabled();
|
||||
await podmanMachineDetails.podmanMachineStopButton.click();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('OFF', { timeout: 50_000 });
|
||||
});
|
||||
|
||||
test('Restart default podman machine', async ({ page, navigationBar }) => {
|
||||
const dashboard = await navigationBar.openDashboard();
|
||||
await playExpect(dashboard.heading).toBeVisible();
|
||||
const settingsBar = await navigationBar.openSettings();
|
||||
await settingsBar.resourcesTab.click();
|
||||
const resourcesPage = new ResourcesPage(page);
|
||||
await playExpect(resourcesPage.heading).toBeVisible();
|
||||
await playExpect.poll(async () => await resourcesPage.resourceCardIsVisible(RESOURCE_NAME)).toBeTruthy();
|
||||
|
||||
const resourcesPodmanConnections = new ResourceConnectionCardPage(
|
||||
page,
|
||||
RESOURCE_NAME,
|
||||
DEFAULT_PODMAN_MACHINE_VISIBLE,
|
||||
);
|
||||
await playExpect(resourcesPodmanConnections.resourceElementDetailsButton).toBeVisible();
|
||||
await resourcesPodmanConnections.resourceElementDetailsButton.click();
|
||||
const podmanMachineDetails = new PodmanMachineDetails(page, DEFAULT_PODMAN_MACHINE);
|
||||
await playExpect(podmanMachineDetails.podmanMachineStartButton).toBeEnabled();
|
||||
await podmanMachineDetails.podmanMachineStartButton.click();
|
||||
await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING', { timeout: 50_000 });
|
||||
await handlePopupDialog(page, 'Yes');
|
||||
await handlePopupDialog(page, 'OK');
|
||||
});
|
||||
|
||||
test('Clean up rootless podman machine', async ({ page }) => {
|
||||
await deletePodmanMachine(page, ROOTLESS_PODMAN_MACHINE_VISIBLE);
|
||||
});
|
||||
|
||||
async function handlePopupDialog(page: Page, action: string): Promise<void> {
|
||||
const dialog = page.getByRole('dialog', { name: 'Podman', exact: true });
|
||||
await playExpect(dialog).toBeVisible();
|
||||
|
||||
const clickOnButton = dialog.getByRole('button', { name: action, exact: true });
|
||||
await playExpect(clickOnButton).toBeEnabled();
|
||||
await clickOnButton.click();
|
||||
}
|
||||
});
|
||||
|
|
@ -177,7 +177,7 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string
|
|||
const RESOURCE_NAME: string = 'podman';
|
||||
const navigationBar = new NavigationBar(page);
|
||||
const dashboardPage = await navigationBar.openDashboard();
|
||||
await playExpect(dashboardPage.mainPage).toBeVisible({ timeout: 3000 });
|
||||
await playExpect(dashboardPage.heading).toBeVisible();
|
||||
const settingsBar = await navigationBar.openSettings();
|
||||
const resourcesPage = await settingsBar.openTabPage(ResourcesPage);
|
||||
await playExpect
|
||||
|
|
|
|||
Loading…
Reference in a new issue