diff --git a/tests/src/model/pages/dashboard-page.ts b/tests/src/model/pages/dashboard-page.ts
index 9880e35042773..4d64436ad6b06 100644
--- a/tests/src/model/pages/dashboard-page.ts
+++ b/tests/src/model/pages/dashboard-page.ts
@@ -24,6 +24,7 @@ export class DashboardPage extends BasePage {
readonly header: Locator;
readonly content: Locator;
readonly heading: Locator;
+ readonly notificationsBox: Locator;
readonly featuredExtensions: Locator;
readonly devSandboxProvider: Locator;
readonly devSandboxBox: Locator;
@@ -37,9 +38,11 @@ export class DashboardPage extends BasePage {
this.mainPage = page.getByRole('region', { name: 'Dashboard' });
this.header = this.mainPage.getByRole('region', { name: 'header' });
this.content = this.mainPage.getByRole('region', { name: 'content' });
- this.featuredExtensions = page.getByLabel('FeaturedExtensions');
this.heading = page.getByRole('heading', { name: 'Dashboard' });
+ this.notificationsBox = this.content.getByRole('region', { name: 'Notifications Box' });
+ this.featuredExtensions = page.getByLabel('FeaturedExtensions');
+
this.devSandboxProvider = page.getByLabel('Developer Sandbox Provider');
this.devSandboxBox = this.featuredExtensions.getByLabel('Developer Sandbox');
this.devSandboxEnabledStatus = this.devSandboxProvider.getByText('RUNNING');
diff --git a/tests/src/model/pages/onboarding-page.ts b/tests/src/model/pages/onboarding-page.ts
new file mode 100644
index 0000000000000..4f1447d091f20
--- /dev/null
+++ b/tests/src/model/pages/onboarding-page.ts
@@ -0,0 +1,39 @@
+/**********************************************************************
+ * 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 { BasePage } from './base-page';
+
+export class OnboardingPage extends BasePage {
+ readonly mainPage: Locator;
+ readonly header: Locator;
+ readonly onboardingComponent: Locator;
+ readonly onboardingStatusMessage: Locator;
+ readonly nextStepButton: Locator;
+ readonly cancelSetupButtion: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.mainPage = page.getByRole('region', { name: 'Onboarding Body' });
+ this.header = this.mainPage.getByRole('heading', { name: 'Header' });
+ this.onboardingComponent = this.mainPage.getByLabel('Onboarding Component');
+ this.onboardingStatusMessage = this.mainPage.getByLabel('Onboarding Status Message');
+ this.nextStepButton = this.mainPage.getByRole('button', { name: 'Next Step' });
+ this.cancelSetupButtion = this.mainPage.getByRole('button', { name: 'Cancel Setup' });
+ }
+}
diff --git a/tests/src/model/pages/podman-machine-details-page.ts b/tests/src/model/pages/podman-machine-details-page.ts
new file mode 100644
index 0000000000000..3647896d28c84
--- /dev/null
+++ b/tests/src/model/pages/podman-machine-details-page.ts
@@ -0,0 +1,44 @@
+/**********************************************************************
+ * 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 { ResourcesPage } from './resources-page';
+
+export class PodmanMachineDetails extends ResourcesPage {
+ readonly podmanMachineName: Locator;
+ readonly podmanMachineStatus: Locator;
+ readonly podmanMachineConnectionActions: Locator;
+ readonly podmanMachineStartButton: Locator;
+ readonly podmanMachineRestartButton: Locator;
+ readonly podmanMachineStopButton: Locator;
+ readonly podmanMachineDeleteButton: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.podmanMachineName = this.getPage().getByRole('heading', { name: 'Podman Machine' });
+ this.podmanMachineStatus = this.getPage().getByLabel('Connection Status Label');
+ this.podmanMachineConnectionActions = this.getPage().getByRole('group', { name: 'Connection Actions' });
+ this.podmanMachineStartButton = this.podmanMachineConnectionActions.getByRole('button', {
+ name: 'Start',
+ exact: true,
+ });
+ this.podmanMachineRestartButton = this.podmanMachineConnectionActions.getByRole('button', { name: 'Restart' });
+ this.podmanMachineStopButton = this.podmanMachineConnectionActions.getByRole('button', { name: 'Stop' });
+ this.podmanMachineDeleteButton = this.podmanMachineConnectionActions.getByRole('button', { name: 'Delete' });
+ }
+}
diff --git a/tests/src/model/pages/podman-onboarding-page.ts b/tests/src/model/pages/podman-onboarding-page.ts
new file mode 100644
index 0000000000000..5ea5a9e25a291
--- /dev/null
+++ b/tests/src/model/pages/podman-onboarding-page.ts
@@ -0,0 +1,62 @@
+/**********************************************************************
+ * 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 { OnboardingPage } from './onboarding-page';
+
+export class PodmanOnboardingPage extends OnboardingPage {
+ readonly podmanAutostartToggle: Locator;
+ readonly createMachinePageTitle: Locator;
+ readonly podmanMachineConfiguration: Locator;
+ readonly podmanMachineName: Locator;
+ readonly podmanMachineCPUs: Locator;
+ readonly podmanMachineMemory: Locator;
+ readonly podmanMachineDiskSize: Locator;
+ readonly podmanMachineImage: Locator;
+ readonly podmanMachineRootfulCheckbox: Locator;
+ readonly podmanMachineUserModeNetworkingCheckbox: Locator;
+ readonly podmanMachineStartAfterCreationCheckbox: Locator;
+ readonly podmanMachineCreateButton: Locator;
+ readonly podmanMachineShowLogsButton: Locator;
+
+ constructor(page: Page) {
+ super(page);
+ this.podmanAutostartToggle = this.mainPage.getByRole('checkbox', {
+ name: 'Autostart Podman engine when launching Podman Desktop',
+ });
+ this.createMachinePageTitle = this.onboardingComponent.getByLabel('title');
+ this.podmanMachineConfiguration = this.mainPage.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' });
+ this.podmanMachineDiskSize = this.podmanMachineConfiguration.getByRole('slider', { name: 'Disk size' });
+ this.podmanMachineImage = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Image Path (Optional)' });
+ this.podmanMachineRootfulCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', {
+ name: 'Machine with root privileges',
+ });
+ this.podmanMachineUserModeNetworkingCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', {
+ name: 'User mode networking',
+ exact: false,
+ });
+ this.podmanMachineStartAfterCreationCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', {
+ name: 'Start the machine now',
+ });
+ this.podmanMachineCreateButton = this.podmanMachineConfiguration.getByRole('button', { name: 'Create' });
+ this.podmanMachineShowLogsButton = this.mainPage.getByRole('button', { name: 'Show Logs' });
+ }
+}
diff --git a/tests/src/model/pages/resources-page.ts b/tests/src/model/pages/resources-page.ts
index 7f85df631c8ad..5ddaa3adea093 100644
--- a/tests/src/model/pages/resources-page.ts
+++ b/tests/src/model/pages/resources-page.ts
@@ -22,10 +22,12 @@ import { SettingsPage } from './settings-page';
export class ResourcesPage extends SettingsPage {
readonly heading: Locator;
readonly featuredProviderResources: Locator;
+ readonly podmanResources: Locator;
constructor(page: Page) {
super(page, 'Resources');
this.heading = page.getByRole('heading', { name: 'Resources' });
this.featuredProviderResources = page.getByRole('region', { name: 'Featured Provider Resources' });
+ this.podmanResources = this.featuredProviderResources.getByRole('region', { name: 'podman', exact: true });
}
}
diff --git a/tests/src/model/pages/resources-podman-connections-page.ts b/tests/src/model/pages/resources-podman-connections-page.ts
new file mode 100644
index 0000000000000..d0b84941b3dbf
--- /dev/null
+++ b/tests/src/model/pages/resources-podman-connections-page.ts
@@ -0,0 +1,45 @@
+/**********************************************************************
+ * 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 { ResourcesPage } from './resources-page';
+
+export class ResourcesPodmanConnections extends ResourcesPage {
+ readonly providerConnections: Locator;
+ readonly podmanMachineElement: Locator;
+ readonly machineConnectionStatus: Locator;
+ readonly machineDetailsButton: Locator;
+ readonly machineConnectionActions: Locator;
+ readonly machineStartButton: Locator;
+ readonly machineRestartButton: Locator;
+ readonly machineStopButton: Locator;
+ readonly machineDeleteButton: Locator;
+
+ constructor(page: Page, machineVisibleName: string) {
+ super(page);
+ this.providerConnections = this.podmanResources.getByRole('region', { name: 'Provider Connections' });
+ this.podmanMachineElement = this.providerConnections.getByRole('region', { name: machineVisibleName });
+ this.machineConnectionStatus = this.podmanMachineElement.getByLabel('Connection Status Label');
+ this.machineDetailsButton = this.podmanMachineElement.getByRole('button', { name: 'Podman details' });
+ this.machineConnectionActions = this.podmanMachineElement.getByRole('group', { name: 'Connection Actions' });
+ this.machineStartButton = this.machineConnectionActions.getByRole('button', { name: 'Start', exact: true });
+ this.machineRestartButton = this.machineConnectionActions.getByRole('button', { name: 'Restart' });
+ this.machineStopButton = this.machineConnectionActions.getByRole('button', { name: 'Stop' });
+ this.machineDeleteButton = this.machineConnectionActions.getByRole('button', { name: 'Delete' });
+ }
+}
diff --git a/tests/src/podman-machine-onboarding.spec.ts b/tests/src/podman-machine-onboarding.spec.ts
new file mode 100644
index 0000000000000..bc2aef5e6283d
--- /dev/null
+++ b/tests/src/podman-machine-onboarding.spec.ts
@@ -0,0 +1,191 @@
+/**********************************************************************
+ * 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';
+import type { RunnerTestContext } from './testContext/runner-test-context';
+import { afterAll, beforeAll, test, describe, beforeEach } from 'vitest';
+import { PodmanDesktopRunner } from './runner/podman-desktop-runner';
+import { WelcomePage } from './model/pages/welcome-page';
+import type { DashboardPage } from './model/pages/dashboard-page';
+import type { Locator } from '@playwright/test';
+import { expect as playExpect } from '@playwright/test';
+import { NavigationBar } from './model/workbench/navigation';
+import type { SettingsBar } from './model/pages/settings-bar';
+import { ResourcesPage } from './model/pages/resources-page';
+import { deletePodmanMachine } from './utility/operations';
+import { PodmanOnboardingPage } from './model/pages/podman-onboarding-page';
+import { ResourcesPodmanConnections } from './model/pages/resources-podman-connections-page';
+import { PodmanMachineDetails } from './model/pages/podman-machine-details-page';
+
+const PODMAN_MACHINE_STARTUP_TIMEOUT: number = 360_000;
+const PODMAN_MACHINE_NAME: string = 'Podman Machine';
+
+let pdRunner: PodmanDesktopRunner;
+let page: Page;
+let dashboardPage: DashboardPage;
+let resourcesPage: ResourcesPage;
+let settingsBar: SettingsBar;
+let navigationBar: NavigationBar;
+let podmanOnboardingPage: PodmanOnboardingPage;
+
+let notificationPodmanSetup: Locator;
+
+beforeAll(async () => {
+ pdRunner = new PodmanDesktopRunner();
+ page = await pdRunner.start();
+ pdRunner.setVideoAndTraceName('podman-machine-e2e');
+
+ const welcomePage = new WelcomePage(page);
+ await welcomePage.handleWelcomePage(true);
+ navigationBar = new NavigationBar(page);
+
+ // Delete machine if it already exists
+ if (
+ (process.env.TEST_PODMAN_MACHINE !== undefined && process.env.TEST_PODMAN_MACHINE === 'true') ||
+ (process.env.MACHINE_CLEANUP !== undefined && process.env.MACHINE_CLEANUP === 'true')
+ ) {
+ await deletePodmanMachine(page, PODMAN_MACHINE_NAME);
+ }
+});
+
+afterAll(async () => {
+ await pdRunner.close();
+}, 120000);
+
+beforeEach
(async ctx => {
+ ctx.pdRunner = pdRunner;
+});
+
+describe('Podman Machine verification', async () => {
+ describe('Podman Machine onboarding workflow', async () => {
+ test('Setup Podman push notification is present', async () => {
+ dashboardPage = await navigationBar.openDashboard();
+ await playExpect(dashboardPage.mainPage).toBeVisible();
+ await playExpect(dashboardPage.notificationsBox).toBeVisible();
+ notificationPodmanSetup = dashboardPage.notificationsBox
+ .getByRole('region', { name: 'id:' })
+ .filter({ hasText: 'Podman needs to be set up' });
+ await playExpect(notificationPodmanSetup).toBeVisible();
+ });
+ describe('Onboarding navigation', async () => {
+ test('Open Podman Machine Onboarding through Setup Notification', async () => {
+ await notificationPodmanSetup.getByTitle('Set up Podman').click();
+ podmanOnboardingPage = await checkPodmanMachineOnboardingPage(page);
+ });
+ test('Return to Dashboard', async () => {
+ dashboardPage = await navigationBar.openDashboard();
+ await playExpect(dashboardPage.mainPage).toBeVisible();
+ });
+ test('Re-Open Podman Machine Onboarding through Settings Resources page', async () => {
+ settingsBar = await navigationBar.openSettings();
+ await settingsBar.resourcesTab.click();
+ resourcesPage = new ResourcesPage(page);
+ await playExpect(resourcesPage.podmanResources).toBeVisible();
+ await resourcesPage.podmanResources.getByLabel('Setup Podman').click();
+ podmanOnboardingPage = await checkPodmanMachineOnboardingPage(page);
+ });
+ });
+ test('Verify Podman Autostart is enabled and proceed to next page', async () => {
+ await playExpect(podmanOnboardingPage.podmanAutostartToggle).toBeChecked();
+ await podmanOnboardingPage.nextStepButton.click();
+ });
+ test('Expect no machine created message and proceed to next page', async () => {
+ await playExpect(podmanOnboardingPage.onboardingStatusMessage).toHaveText(
+ `We could not find any Podman machine. Let's create one!`,
+ );
+ await podmanOnboardingPage.nextStepButton.click();
+ });
+ test('Verify default podman machine settings', async () => {
+ await playExpect(podmanOnboardingPage.createMachinePageTitle).toHaveText(`Create a Podman machine`);
+ await playExpect(podmanOnboardingPage.podmanMachineConfiguration).toBeVisible();
+ await playExpect(podmanOnboardingPage.podmanMachineName).toHaveValue('podman-machine-default');
+ await playExpect(podmanOnboardingPage.podmanMachineCPUs).toBeVisible();
+ await playExpect(podmanOnboardingPage.podmanMachineMemory).toBeVisible();
+ await playExpect(podmanOnboardingPage.podmanMachineDiskSize).toBeVisible();
+ await playExpect(podmanOnboardingPage.podmanMachineImage).toHaveValue('');
+ await playExpect(podmanOnboardingPage.podmanMachineRootfulCheckbox).toBeChecked();
+ await playExpect(podmanOnboardingPage.podmanMachineUserModeNetworkingCheckbox).not.toBeChecked();
+ await playExpect(podmanOnboardingPage.podmanMachineStartAfterCreationCheckbox).toBeChecked();
+ });
+ });
+ describe.runIf(process.env.TEST_PODMAN_MACHINE !== undefined && process.env.TEST_PODMAN_MACHINE === 'true')(
+ 'Podman Machine creation and operations',
+ async () => {
+ test('Create a default Podman machine', async () => {
+ await podmanOnboardingPage.podmanMachineCreateButton.click();
+ await playExpect(podmanOnboardingPage.podmanMachineShowLogsButton).toBeVisible();
+ await podmanOnboardingPage.podmanMachineShowLogsButton.click();
+ await playExpect(podmanOnboardingPage.onboardingStatusMessage).toBeVisible({
+ timeout: PODMAN_MACHINE_STARTUP_TIMEOUT,
+ });
+ await playExpect(podmanOnboardingPage.onboardingStatusMessage).toHaveText('Podman successfully setup');
+ await podmanOnboardingPage.nextStepButton.click();
+ });
+ describe('Podman machine operations', async () => {
+ let podmanMachineDetails: PodmanMachineDetails;
+ test('Open podman machine details', async () => {
+ dashboardPage = await navigationBar.openDashboard();
+ await playExpect(dashboardPage.mainPage).toBeVisible();
+ settingsBar = await navigationBar.openSettings();
+ await settingsBar.resourcesTab.click();
+ resourcesPage = new ResourcesPage(page);
+ await playExpect(resourcesPage.podmanResources).toBeVisible();
+ const resourcesPodmanConnections = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME);
+ await playExpect(resourcesPodmanConnections.providerConnections).toBeVisible({ timeout: 10_000 });
+ await playExpect(resourcesPodmanConnections.podmanMachineElement).toBeVisible();
+ await playExpect(resourcesPodmanConnections.machineDetailsButton).toBeVisible();
+ await resourcesPodmanConnections.machineDetailsButton.click();
+ podmanMachineDetails = new PodmanMachineDetails(page);
+ 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();
+ });
+ test('Podman machine operations - STOP', async () => {
+ await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING', { timeout: 30_000 });
+ await podmanMachineDetails.podmanMachineStopButton.click();
+ await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('OFF', { timeout: 30_000 });
+ });
+ test('Podman machine operations - START', async () => {
+ await podmanMachineDetails.podmanMachineStartButton.click();
+ await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING', { timeout: 30_000 });
+ });
+ test('Podman machine operations - RESTART', async () => {
+ await podmanMachineDetails.podmanMachineRestartButton.click();
+ await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('OFF', { timeout: 30_000 });
+ await playExpect(podmanMachineDetails.podmanMachineStatus).toHaveText('RUNNING', { timeout: 30_000 });
+ });
+ });
+ },
+ );
+ test.runIf(process.env.MACHINE_CLEANUP !== undefined && process.env.MACHINE_CLEANUP === 'true')(
+ 'Clean Up Podman Machine',
+ async () => {
+ await deletePodmanMachine(page, 'Podman Machine');
+ },
+ );
+});
+
+async function checkPodmanMachineOnboardingPage(page: Page): Promise {
+ const onboardingPage = new PodmanOnboardingPage(page);
+ await playExpect(onboardingPage.header).toBeVisible();
+ await playExpect(onboardingPage.mainPage).toBeVisible();
+ return onboardingPage;
+}
diff --git a/tests/src/utility/operations.ts b/tests/src/utility/operations.ts
index 66c6293445f2c..63099f3f68f57 100644
--- a/tests/src/utility/operations.ts
+++ b/tests/src/utility/operations.ts
@@ -16,10 +16,13 @@
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/
-import { type Page } from '@playwright/test';
+import type { Page } from '@playwright/test';
import { NavigationBar } from '../model/workbench/navigation';
import { waitUntil, waitWhile } from './wait';
+import { ResourcesPage } from '../model/pages/resources-page';
import { RegistriesPage } from '../model/pages/registries-page';
+import { expect as playExpect } from '@playwright/test';
+import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page';
/**
* Stop and delete container defined by its name
@@ -156,3 +159,42 @@ export async function handleConfirmationDialog(
const button = confirm ? dialog.getByRole('button', { name: 'Yes' }) : dialog.getByRole('button', { name: 'Cancel' });
await button.click();
}
+
+/**
+ * Async function that stops and deletes Podman Machine through Settings -> Resources page
+ * @param page playwright's page object
+ * @param machineVisibleName Name of the Podman Machine to delete
+ */
+export async function deletePodmanMachine(page: Page, machineVisibleName: string): Promise {
+ const navigationBar = new NavigationBar(page);
+ const dashboardPage = await navigationBar.openDashboard();
+ await playExpect(dashboardPage.mainPage).toBeVisible({ timeout: 3000 });
+ const settingsBar = await navigationBar.openSettings();
+ const resourcesPage = await settingsBar.openTabPage(ResourcesPage);
+ await playExpect(resourcesPage.podmanResources).toBeVisible({ timeout: 10_000 });
+ const resourcesPodmanConnections = new ResourcesPodmanConnections(page, machineVisibleName);
+ await playExpect(resourcesPodmanConnections.providerConnections).toBeVisible({ timeout: 10_000 });
+ await waitWhile(
+ async () => {
+ return (await resourcesPodmanConnections.podmanMachineElement.isVisible()) ? false : true;
+ },
+ 10_000,
+ 1000,
+ false,
+ );
+ if (await resourcesPodmanConnections.podmanMachineElement.isVisible()) {
+ await playExpect(resourcesPodmanConnections.machineConnectionActions).toBeVisible({ timeout: 3000 });
+ await playExpect(resourcesPodmanConnections.machineConnectionStatus).toBeVisible({ timeout: 3000 });
+ if ((await resourcesPodmanConnections.machineConnectionStatus.innerText()) === 'RUNNING') {
+ await playExpect(resourcesPodmanConnections.machineStopButton).toBeVisible({ timeout: 3000 });
+ await resourcesPodmanConnections.machineStopButton.click();
+ await playExpect(resourcesPodmanConnections.machineConnectionStatus).toHaveText('OFF', { timeout: 30_000 });
+ }
+ await playExpect(resourcesPodmanConnections.machineDeleteButton).toBeVisible({ timeout: 3000 });
+ await waitWhile(() => resourcesPodmanConnections.machineDeleteButton.isDisabled(), 10_000, 1000, true);
+ await resourcesPodmanConnections.machineDeleteButton.click();
+ await playExpect(resourcesPodmanConnections.podmanMachineElement).toBeHidden({ timeout: 30_000 });
+ } else {
+ console.log(`Podman machine [${machineVisibleName}] not present, skipping deletion.`);
+ }
+}