From 04c6098a11641a446b1a2c4317eb33c8f44f108f Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Fri, 26 Apr 2024 02:15:15 +0200 Subject: [PATCH 01/53] chore(tests): rootless machine creation test added Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 76 +++++++++++++++++++ .../src/specs/podman-machine-rootless.spec.ts | 74 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 tests/playwright/src/model/pages/create-machine-page.ts create mode 100644 tests/playwright/src/specs/podman-machine-rootless.spec.ts diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts new file mode 100644 index 0000000000000..1c3eef3d295f5 --- /dev/null +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -0,0 +1,76 @@ +/********************************************************************** + * Copyright (C) 2023 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 { expect as playExpect } from '@playwright/test'; + +import { BasePage } from './base-page'; +import { ResourcesPage } from './resources-page'; + +export class CreateMachinePage extends BasePage { + readonly heading: Locator; + readonly machineNameBox: Locator; + readonly cpuSlider: Locator; + readonly memorySlider: Locator; + readonly diskSlider: Locator; + readonly imagePathBox: Locator; + readonly browseImagesButton: Locator; + readonly rootPriviledgesCheckbox: Locator; + readonly userModeNetworkingCheckbox: Locator; + readonly startNowCheckbox: Locator; + readonly closeButton: Locator; + readonly createMachineButton: Locator; + + constructor(page: Page) { + super(page); + this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); + this.machineNameBox = this.page.getByRole('textbox', { name: 'Name' }); + this.cpuSlider = this.page.getByRole('slider', { name: 'CPU(s)' }); + this.memorySlider = this.page.getByRole('slider', { name: 'Memory' }); + this.diskSlider = this.page.getByRole('slider', { name: 'Disk size' }); + this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); + this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); + this.rootPriviledgesCheckbox = this.page.getByRole('checkbox', { name: 'Machine with root priviledges' }); + this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { + name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', + }); + this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); + this.closeButton = this.page.getByRole('button', { name: 'Close page' }); + this.createMachineButton = this.page.getByRole('button', { name: 'Create Pod' }); + } + + async createMachine(machineName: string, isRootless: boolean): Promise { + //can be extended + await this.machineNameBox.fill(machineName); + if (!isRootless) { + await this.rootPriviledgesCheckbox.uncheck(); + playExpect(this.rootPriviledgesCheckbox.isChecked()).toBeFalsy(); + } + + await this.createMachineButton.click(); + + const successfulCreationMessage = this.page.getByLabel('Successful operation'); + const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); + + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 50000 }); + await playExpect(goBackToResourcesButton).toBeVisible(); + await goBackToResourcesButton.click(); + + return new ResourcesPage(this.page); + } +} diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts new file mode 100644 index 0000000000000..692626c067f64 --- /dev/null +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -0,0 +1,74 @@ +/********************************************************************** + * 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 { expect as playExpect } from '@playwright/test'; +import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; + +import { CreateMachinePage } from '../model/pages/create-machine-page'; +import { ResourcesPage } from '../model/pages/resources-page'; +import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page'; +import { WelcomePage } from '../model/pages/welcome-page'; +import { NavigationBar } from '../model/workbench/navigation'; +import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; +import type { RunnerTestContext } from '../testContext/runner-test-context'; +import { deletePodmanMachine } from '../utility/operations'; + +let pdRunner: PodmanDesktopRunner; +let page: Page; +let navBar: NavigationBar; +const PODMAN_MACHINE_NAME: string = 'Podman Machine Rootless'; + +beforeAll(async () => { + pdRunner = new PodmanDesktopRunner(); + page = await pdRunner.start(); + pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); + + const welcomePage = new WelcomePage(page); + await welcomePage.handleWelcomePage(true); + navBar = new NavigationBar(page); +}); + +afterAll(async () => { + await deletePodmanMachine(page, PODMAN_MACHINE_NAME); + await pdRunner.close(); +}); + +beforeEach(async ctx => { + ctx.pdRunner = pdRunner; +}); + +describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { + test('Create a rootless machine', async () => { + await navBar.openSettings(); + const resourcesPage = new ResourcesPage(page); + + const createMachineButton = resourcesPage.podmanResources.getByRole('button', { + name: 'Create new Podman machine', + }); + await createMachineButton.click(); + + const createMachinePage = new CreateMachinePage(page); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); + + const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); + const connectionStatus = await machineBox.machineConnectionStatus.allTextContents(); + playExpect(connectionStatus[0] === 'RUNNING').toBeTruthy(); + }); +}); From 52f77d02e13c9c34eca6246ad11a4e9f65f01339 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 02/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 34 ++++++++++--------- .../src/specs/podman-machine-rootless.spec.ts | 8 +++-- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 1c3eef3d295f5..472c6af4a9551 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. @@ -25,9 +25,7 @@ import { ResourcesPage } from './resources-page'; export class CreateMachinePage extends BasePage { readonly heading: Locator; readonly machineNameBox: Locator; - readonly cpuSlider: Locator; - readonly memorySlider: Locator; - readonly diskSlider: Locator; + readonly podmanMachineConfiguration: Locator; readonly imagePathBox: Locator; readonly browseImagesButton: Locator; readonly rootPriviledgesCheckbox: Locator; @@ -39,35 +37,39 @@ export class CreateMachinePage extends BasePage { constructor(page: Page) { super(page); this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); - this.machineNameBox = this.page.getByRole('textbox', { name: 'Name' }); - this.cpuSlider = this.page.getByRole('slider', { name: 'CPU(s)' }); - this.memorySlider = this.page.getByRole('slider', { name: 'Memory' }); - this.diskSlider = this.page.getByRole('slider', { name: 'Disk size' }); + this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); + + this.machineNameBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); - this.rootPriviledgesCheckbox = this.page.getByRole('checkbox', { name: 'Machine with root priviledges' }); + this.rootPriviledgesCheckbox = this.podmanMachineConfiguration + .getByRole('checkbox', { name: 'Machine with root privileges' }) + .locator('..'); this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', }); this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); - this.closeButton = this.page.getByRole('button', { name: 'Close page' }); - this.createMachineButton = this.page.getByRole('button', { name: 'Create Pod' }); + this.closeButton = this.page.getByRole('button', { name: 'Close' }); + this.createMachineButton = this.page.getByRole('button', { name: 'Create' }); } async createMachine(machineName: string, isRootless: boolean): Promise { - //can be extended + await playExpect(this.podmanMachineConfiguration).toBeVisible(); await this.machineNameBox.fill(machineName); + if (!isRootless) { - await this.rootPriviledgesCheckbox.uncheck(); - playExpect(this.rootPriviledgesCheckbox.isChecked()).toBeFalsy(); + await playExpect(this.rootPriviledgesCheckbox).toBeVisible(); + const upperElement = this.rootPriviledgesCheckbox.locator('..'); + const clickableCheckbox = upperElement.getByText('Enable'); + await clickableCheckbox.click(); } await this.createMachineButton.click(); - const successfulCreationMessage = this.page.getByLabel('Successful operation'); + const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 50000 }); + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 100000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 692626c067f64..22b59ea99d581 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -68,7 +68,9 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); - const connectionStatus = await machineBox.machineConnectionStatus.allTextContents(); - playExpect(connectionStatus[0] === 'RUNNING').toBeTruthy(); - }); + const connectionStatusLabel = await machineBox.machineConnectionStatus + .getByLabel('Connection Status Label') + .textContent(); + playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); + }, 150000); }); From b8b569297cf2ea96674be85cbac8dcfc6d1c85fb Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 03/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 72 ++++++++++++++----- .../src/specs/podman-machine-rootless.spec.ts | 11 ++- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 472c6af4a9551..2000d3e86dd98 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. @@ -24,10 +24,13 @@ import { ResourcesPage } from './resources-page'; export class CreateMachinePage extends BasePage { readonly heading: Locator; - readonly machineNameBox: Locator; + readonly podmanMachineName: Locator; readonly podmanMachineConfiguration: Locator; readonly imagePathBox: Locator; readonly browseImagesButton: Locator; + readonly podmanMachineCPUs: Locator; + readonly podmanMachineMemory: Locator; + readonly podmanMachineDiskSize: Locator; readonly rootPriviledgesCheckbox: Locator; readonly userModeNetworkingCheckbox: Locator; readonly startNowCheckbox: Locator; @@ -38,30 +41,42 @@ export class CreateMachinePage extends BasePage { super(page); this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); - - this.machineNameBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); + this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); - this.rootPriviledgesCheckbox = this.podmanMachineConfiguration - .getByRole('checkbox', { name: 'Machine with root privileges' }) - .locator('..'); - this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { - name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', + 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.rootPriviledgesCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'Machine with root privileges', + }); + this.userModeNetworkingCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'User mode networking', }); - this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); + this.startNowCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { name: 'Start the machine now' }); this.closeButton = this.page.getByRole('button', { name: 'Close' }); this.createMachineButton = this.page.getByRole('button', { name: 'Create' }); } - async createMachine(machineName: string, isRootless: boolean): Promise { + async createMachine( + machineName: string, + isRootful: boolean = true, + enableUserNet: boolean = false, + startNow: boolean = true, + ): Promise { await playExpect(this.podmanMachineConfiguration).toBeVisible(); - await this.machineNameBox.fill(machineName); + await this.podmanMachineName.fill(machineName); + + if (isRootful !== (await this.isEnabled(this.rootPriviledgesCheckbox))) { + await this.switchCheckbox(this.rootPriviledgesCheckbox); + } - if (!isRootless) { - await playExpect(this.rootPriviledgesCheckbox).toBeVisible(); - const upperElement = this.rootPriviledgesCheckbox.locator('..'); - const clickableCheckbox = upperElement.getByText('Enable'); - await clickableCheckbox.click(); + if (enableUserNet !== (await this.isEnabled(this.userModeNetworkingCheckbox))) { + await this.switchCheckbox(this.userModeNetworkingCheckbox); + } + + if (startNow !== (await this.isEnabled(this.startNowCheckbox))) { + await this.switchCheckbox(this.startNowCheckbox); } await this.createMachineButton.click(); @@ -75,4 +90,27 @@ export class CreateMachinePage extends BasePage { return new ResourcesPage(this.page); } + + async isEnabled(checkbox: Locator): Promise { + await playExpect(checkbox).toBeVisible(); + const upperElement = checkbox.locator('..').locator('..'); + const clickableCheckbox = upperElement.getByText('Enabled'); + return await clickableCheckbox.isVisible(); + } + + async switchCheckbox(checkbox: Locator): Promise { + await playExpect(checkbox).toBeVisible(); + const upperElement = checkbox.locator('..').locator('..'); + + const wasEnabled = await this.isEnabled(checkbox); + let checkText; + if (wasEnabled) { + checkText = 'Enabled'; + } else { + checkText = 'Disabled'; + } + + const clickableCheckbox = upperElement.getByText(checkText); + await clickableCheckbox.click(); + } } diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 22b59ea99d581..522b592fbc8dc 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -33,7 +33,8 @@ import { deletePodmanMachine } from '../utility/operations'; let pdRunner: PodmanDesktopRunner; let page: Page; let navBar: NavigationBar; -const PODMAN_MACHINE_NAME: string = 'Podman Machine Rootless'; +const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; +const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); @@ -65,12 +66,10 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true); - const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); - const connectionStatusLabel = await machineBox.machineConnectionStatus - .getByLabel('Connection Status Label') - .textContent(); + const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); + const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); }, 150000); }); From a2c5ceeed68c3b2629d1a4d411cb8926919eb310 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 9 Jul 2024 08:01:56 +0200 Subject: [PATCH 04/53] chore(tests): addressing changes 2 Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 2000d3e86dd98..02bb2c71aaf3d 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -42,8 +42,10 @@ export class CreateMachinePage extends BasePage { this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); - this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); - this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); + this.imagePathBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Image Path (Optional) ' }); + this.browseImagesButton = this.podmanMachineConfiguration.getByRole('button', { + name: 'button-Image Path (Optional)', + }); 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' }); From cf3d0deaf85793a42dc2549301a06b8c6ba46265 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 6 Aug 2024 00:21:13 +0200 Subject: [PATCH 05/53] chore(tests): added connection dialog handling Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 25 ++++++++++++++++++- .../src/specs/podman-machine-rootless.spec.ts | 6 +++-- tests/playwright/src/utility/operations.ts | 12 +++++---- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 02bb2c71aaf3d..e055a7e2f11fa 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -65,6 +65,7 @@ export class CreateMachinePage extends BasePage { isRootful: boolean = true, enableUserNet: boolean = false, startNow: boolean = true, + setAsDefault: boolean = true, ): Promise { await playExpect(this.podmanMachineConfiguration).toBeVisible(); await this.podmanMachineName.fill(machineName); @@ -82,11 +83,14 @@ export class CreateMachinePage extends BasePage { } await this.createMachineButton.click(); + await this.page.waitForTimeout(60000); const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 100000 }); + await this.handleConnectionDialog(machineName, setAsDefault); + + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); @@ -115,4 +119,23 @@ export class CreateMachinePage extends BasePage { const clickableCheckbox = upperElement.getByText(checkText); await clickableCheckbox.click(); } + + async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise { + const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); + const dialogMessage = connectionDialog.getByText( + new RegExp( + "Podman Machine '" + + machineName + + "' is running but not the default machine .+ Do you want to set it as default?", + ), + ); + if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) { + let handleButtonName = 'Yes'; + if (!setAsDefault) { + handleButtonName = 'Ignore'; + } + const handleButton = connectionDialog.getByRole('button', { name: handleButtonName }); + await handleButton.click(); + } + } } diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 522b592fbc8dc..c9cde379e53b7 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -40,6 +40,7 @@ beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); page = await pdRunner.start(); pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); + process.env.KEEP_TRACES_ON_PASS = 'true'; const welcomePage = new WelcomePage(page); await welcomePage.handleWelcomePage(true); @@ -47,7 +48,7 @@ beforeAll(async () => { }); afterAll(async () => { - await deletePodmanMachine(page, PODMAN_MACHINE_NAME); + await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); await pdRunner.close(); }); @@ -66,7 +67,8 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); + await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); diff --git a/tests/playwright/src/utility/operations.ts b/tests/playwright/src/utility/operations.ts index 372f85c8b02ec..bd9c78ec62b5e 100644 --- a/tests/playwright/src/utility/operations.ts +++ b/tests/playwright/src/utility/operations.ts @@ -185,10 +185,10 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string const podmanResourceCard = new ResourceConnectionCardPage(page, RESOURCE_NAME, machineVisibleName); await playExpect(podmanResourceCard.providerConnections).toBeVisible({ timeout: 10_000 }); await waitUntil( - async () => { - return await podmanResourceCard.resourceElement.isVisible(); + async function machineExists() { + return await resourcesPodmanConnections.podmanMachineElement.isVisible(); }, - { timeout: 15000 }, + { timeout: 15000, sendError: false }, ); if (await podmanResourceCard.resourceElement.isVisible()) { await playExpect(podmanResourceCard.resourceElementConnectionActions).toBeVisible({ timeout: 3000 }); @@ -208,8 +208,10 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string timeout: 30_000, }); } - await podmanResourceCard.performConnectionAction(ResourceElementActions.Delete); - await playExpect(podmanResourceCard.resourceElement).toBeHidden({ timeout: 30_000 }); + await playExpect(resourcesPodmanConnections.machineDeleteButton).toBeVisible({ timeout: 3000 }); + await waitWhile(() => resourcesPodmanConnections.machineDeleteButton.isDisabled(), { timeout: 10000 }); + await resourcesPodmanConnections.machineDeleteButton.click(); + await playExpect(resourcesPodmanConnections.podmanMachineElement).toBeHidden({ timeout: 60_000 }); } else { console.log(`Podman machine [${machineVisibleName}] not present, skipping deletion.`); } From 65197d07e95cc36141ff73c9ed5792d57a94e7e8 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 06/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index e055a7e2f11fa..69569aadd347a 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. From ca30dd651e910496e51672b017dbb69fd41c1b7a Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 07/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 69569aadd347a..e055a7e2f11fa 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. From cbe0071f97a76c7b65d2369288e008754248370a Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Thu, 8 Aug 2024 09:50:11 +0200 Subject: [PATCH 08/53] chore(tests): solving conflicts Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 4 +--- .../src/specs/podman-machine-rootless.spec.ts | 14 +++++--------- tests/playwright/src/utility/operations.ts | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index e055a7e2f11fa..6e91247b7ed69 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -124,9 +124,7 @@ export class CreateMachinePage extends BasePage { const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); const dialogMessage = connectionDialog.getByText( new RegExp( - "Podman Machine '" + - machineName + - "' is running but not the default machine .+ Do you want to set it as default?", + `Podman Machine '${machineName}' is running but not the default machine .+ Do you want to set it as default?`, ), ); if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) { diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index c9cde379e53b7..ff5b6c9d70c57 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -22,8 +22,7 @@ import { expect as playExpect } from '@playwright/test'; import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; import { CreateMachinePage } from '../model/pages/create-machine-page'; -import { ResourcesPage } from '../model/pages/resources-page'; -import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page'; +import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; import { WelcomePage } from '../model/pages/welcome-page'; import { NavigationBar } from '../model/workbench/navigation'; import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; @@ -59,19 +58,16 @@ beforeEach(async ctx => { describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { test('Create a rootless machine', async () => { await navBar.openSettings(); - const resourcesPage = new ResourcesPage(page); + const podmanResources = new ResourceConnectionCardPage(page, 'podman'); - const createMachineButton = resourcesPage.podmanResources.getByRole('button', { - name: 'Create new Podman machine', - }); - await createMachineButton.click(); + await podmanResources.createButton.click(); const createMachinePage = new CreateMachinePage(page); await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); - const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); - const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); + const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); + const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); }, 150000); }); diff --git a/tests/playwright/src/utility/operations.ts b/tests/playwright/src/utility/operations.ts index bd9c78ec62b5e..84eb85a2bb557 100644 --- a/tests/playwright/src/utility/operations.ts +++ b/tests/playwright/src/utility/operations.ts @@ -186,7 +186,7 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string await playExpect(podmanResourceCard.providerConnections).toBeVisible({ timeout: 10_000 }); await waitUntil( async function machineExists() { - return await resourcesPodmanConnections.podmanMachineElement.isVisible(); + return await podmanResourceCard.resourceElement.isVisible(); }, { timeout: 15000, sendError: false }, ); From cd9b87375c2be8ab1613485b9d285ebb7540df3b Mon Sep 17 00:00:00 2001 From: xbabalov Date: Mon, 19 Aug 2024 22:24:22 +0200 Subject: [PATCH 09/53] chore(tests): number refactoring Signed-off-by: xbabalov --- .../src/model/pages/create-machine-page.ts | 4 ++-- .../src/specs/podman-machine-rootless.spec.ts | 2 +- tests/playwright/src/utility/operations.ts | 20 +++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 6e91247b7ed69..2270bd19b379d 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -83,14 +83,14 @@ export class CreateMachinePage extends BasePage { } await this.createMachineButton.click(); - await this.page.waitForTimeout(60000); + await this.page.waitForTimeout(60_000); const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); await this.handleConnectionDialog(machineName, setAsDefault); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10000 }); + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10_000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index ff5b6c9d70c57..f1c1b853f26b4 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -69,5 +69,5 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); - }, 150000); + }, 150_000); }); diff --git a/tests/playwright/src/utility/operations.ts b/tests/playwright/src/utility/operations.ts index 84eb85a2bb557..a28cf959bbfb1 100644 --- a/tests/playwright/src/utility/operations.ts +++ b/tests/playwright/src/utility/operations.ts @@ -57,7 +57,7 @@ export async function deleteContainer(page: Page, name: string): Promise { // wait for container to disappear try { console.log('Waiting for container to get deleted ...'); - await playExpect.poll(async () => await containers.getContainerRowByName(name), { timeout: 30000 }).toBeFalsy(); + await playExpect.poll(async () => await containers.getContainerRowByName(name), { timeout: 10_000 }).toBeFalsy(); } catch (error) { if (!(error as Error).message.includes('Page is empty')) { throw Error(`Error waiting for container '${name}' to get removed, ${error}`); @@ -79,7 +79,7 @@ export async function deleteImage(page: Page, name: string): Promise { console.log(`image '${name}' does not exist, skipping...`); } else { const deleteButton = row.getByRole('button', { name: 'Delete Image' }); - if (await deleteButton.isEnabled({ timeout: 2000 })) { + if (await deleteButton.isEnabled({ timeout: 2_000 })) { await deleteButton.click(); await handleConfirmationDialog(page); } else { @@ -94,7 +94,7 @@ export async function deleteImage(page: Page, name: string): Promise { const result = await images.getImageRowByName(name); return !!result; }, - { timeout: 10000, sendError: false }, + { timeout: 10_000, sendError: false }, ); } catch (error) { if (!(error as Error).message.includes('Page is empty')) { @@ -140,7 +140,7 @@ export async function deletePod(page: Page, name: string): Promise { async () => { return !!(await pods.getPodRowByName(name)); }, - { timeout: 20000 }, + { timeout: 20_000 }, ); } catch (error) { if (!(error as Error).message.includes('Page is empty')) { @@ -160,7 +160,7 @@ export async function handleConfirmationDialog( ): Promise { // wait for dialog to appear using waitFor const dialog = page.getByRole('dialog', { name: dialogTitle, exact: true }); - await dialog.waitFor({ state: 'visible', timeout: 3000 }); + await dialog.waitFor({ state: 'visible', timeout: 3_000 }); const button = confirm ? dialog.getByRole('button', { name: confirmationButton }) : dialog.getByRole('button', { name: cancelButton }); @@ -176,11 +176,11 @@ 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.mainPage).toBeVisible({ timeout: 3_000 }); const settingsBar = await navigationBar.openSettings(); const resourcesPage = await settingsBar.openTabPage(ResourcesPage); await playExpect - .poll(async () => await resourcesPage.resourceCardIsVisible(RESOURCE_NAME), { timeout: 10000 }) + .poll(async () => await resourcesPage.resourceCardIsVisible(RESOURCE_NAME), { timeout: 10_000 }) .toBeTruthy(); const podmanResourceCard = new ResourceConnectionCardPage(page, RESOURCE_NAME, machineVisibleName); await playExpect(podmanResourceCard.providerConnections).toBeVisible({ timeout: 10_000 }); @@ -188,11 +188,11 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string async function machineExists() { return await podmanResourceCard.resourceElement.isVisible(); }, - { timeout: 15000, sendError: false }, + { timeout: 15_000, sendError: false }, ); if (await podmanResourceCard.resourceElement.isVisible()) { - await playExpect(podmanResourceCard.resourceElementConnectionActions).toBeVisible({ timeout: 3000 }); - await playExpect(podmanResourceCard.resourceElementConnectionStatus).toBeVisible({ timeout: 3000 }); + await playExpect(podmanResourceCard.resourceElementConnectionActions).toBeVisible({ timeout: 3_000 }); + await playExpect(podmanResourceCard.resourceElementConnectionStatus).toBeVisible({ timeout: 3_000 }); if ((await podmanResourceCard.resourceElementConnectionStatus.innerText()) === ResourceElementState.Starting) { console.log('Podman machine is in starting currently, will send stop command via CLI'); // eslint-disable-next-line sonarjs/os-command From 3a5d37b9d8e8c6ae3dc43b7336f72bc4ab0ed167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tamara=20Bab=C3=A1lov=C3=A1?= Date: Thu, 5 Sep 2024 02:54:09 -0700 Subject: [PATCH 10/53] =?UTF-8?q?chore(tests):=20fixing=20test=20runtime?= =?UTF-8?q?=20Signed-off-by:=20Tamara=20Bab=C3=A1lov=C3=A1=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/playwright/src/index.ts | 1 + .../src/model/pages/create-machine-page.ts | 28 ++++++++--------- .../pages/resource-connection-card-page.ts | 5 ++- .../src/specs/podman-machine-rootless.spec.ts | 31 ++++++++++--------- tests/playwright/src/utility/operations.ts | 21 ++++++++++--- 5 files changed, 51 insertions(+), 35 deletions(-) diff --git a/tests/playwright/src/index.ts b/tests/playwright/src/index.ts index 45cc039008a9d..10fe825dff459 100644 --- a/tests/playwright/src/index.ts +++ b/tests/playwright/src/index.ts @@ -43,6 +43,7 @@ export * from './model/pages/compose-onboarding/compose-wide-install-page'; export * from './model/pages/container-details-page'; export * from './model/pages/containers-page'; export * from './model/pages/create-kind-cluster-page'; +export * from './model/pages/create-machine-page'; export * from './model/pages/create-pod-page'; export * from './model/pages/dashboard-page'; export * from './model/pages/deploy-to-kubernetes-page'; diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 2270bd19b379d..8d6167b33dceb 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -19,6 +19,8 @@ import type { Locator, Page } from '@playwright/test'; import { expect as playExpect } from '@playwright/test'; +import { delay } from '/@/utility/wait'; + import { BasePage } from './base-page'; import { ResourcesPage } from './resources-page'; @@ -62,25 +64,14 @@ export class CreateMachinePage extends BasePage { async createMachine( machineName: string, - isRootful: boolean = true, - enableUserNet: boolean = false, - startNow: boolean = true, - setAsDefault: boolean = true, + { isRootful = true, enableUserNet = false, startNow = true, setAsDefault = true }, ): Promise { await playExpect(this.podmanMachineConfiguration).toBeVisible(); await this.podmanMachineName.fill(machineName); - if (isRootful !== (await this.isEnabled(this.rootPriviledgesCheckbox))) { - await this.switchCheckbox(this.rootPriviledgesCheckbox); - } - - if (enableUserNet !== (await this.isEnabled(this.userModeNetworkingCheckbox))) { - await this.switchCheckbox(this.userModeNetworkingCheckbox); - } - - if (startNow !== (await this.isEnabled(this.startNowCheckbox))) { - await this.switchCheckbox(this.startNowCheckbox); - } + await this.ensureCheckboxState(isRootful, this.rootPriviledgesCheckbox); + await this.ensureCheckboxState(enableUserNet, this.userModeNetworkingCheckbox); + await this.ensureCheckboxState(startNow, this.startNowCheckbox); await this.createMachineButton.click(); await this.page.waitForTimeout(60_000); @@ -88,6 +79,7 @@ export class CreateMachinePage extends BasePage { const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); + await delay(5000); await this.handleConnectionDialog(machineName, setAsDefault); await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10_000 }); @@ -97,6 +89,12 @@ export class CreateMachinePage extends BasePage { return new ResourcesPage(this.page); } + async ensureCheckboxState(desiredState: boolean, checkbox: Locator): Promise { + if (desiredState !== (await this.isEnabled(checkbox))) { + await this.switchCheckbox(checkbox); + } + } + async isEnabled(checkbox: Locator): Promise { await playExpect(checkbox).toBeVisible(); const upperElement = checkbox.locator('..').locator('..'); diff --git a/tests/playwright/src/model/pages/resource-connection-card-page.ts b/tests/playwright/src/model/pages/resource-connection-card-page.ts index 3e55ea91b64e6..cbba2d9684832 100644 --- a/tests/playwright/src/model/pages/resource-connection-card-page.ts +++ b/tests/playwright/src/model/pages/resource-connection-card-page.ts @@ -30,7 +30,10 @@ export class ResourceConnectionCardPage extends ResourceCardPage { constructor(page: Page, resourceName: string, resourceElementVisibleName?: string) { super(page, resourceName); - this.resourceElement = this.providerConnections.getByRole('region', { name: resourceElementVisibleName }); + this.resourceElement = this.providerConnections.getByRole('region', { + name: resourceElementVisibleName, + exact: true, + }); this.resourceElementDetailsButton = this.resourceElement.getByRole('button', { name: 'details' }); this.resourceElementConnectionStatus = this.resourceElement.getByLabel('Connection Status Label'); this.resourceElementConnectionActions = this.resourceElement.getByRole('group', { name: 'Connection Actions' }); diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index f1c1b853f26b4..4bf7215c79c5e 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -18,16 +18,16 @@ import * as os from 'node:os'; import type { Page } from '@playwright/test'; -import { expect as playExpect } from '@playwright/test'; -import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; +import { expect as playExpect, test } from '@playwright/test'; +import { ResourceElementState } from '../model/core/states'; import { CreateMachinePage } from '../model/pages/create-machine-page'; import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; import { WelcomePage } from '../model/pages/welcome-page'; import { NavigationBar } from '../model/workbench/navigation'; import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; -import type { RunnerTestContext } from '../testContext/runner-test-context'; import { deletePodmanMachine } from '../utility/operations'; +import { delay } from '../utility/wait'; let pdRunner: PodmanDesktopRunner; let page: Page; @@ -35,7 +35,7 @@ let navBar: NavigationBar; const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; -beforeAll(async () => { +test.beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); page = await pdRunner.start(); pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); @@ -46,28 +46,31 @@ beforeAll(async () => { navBar = new NavigationBar(page); }); -afterAll(async () => { - await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); +test.afterAll(async () => { await pdRunner.close(); }); -beforeEach(async ctx => { - ctx.pdRunner = pdRunner; -}); +test.describe('Rootless Podman machine Verification', () => { + test.skip(os.platform() === 'linux', 'runs only on windows and mac'); -describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { test('Create a rootless machine', async () => { + test.setTimeout(200000); + await navBar.openSettings(); const podmanResources = new ResourceConnectionCardPage(page, 'podman'); await podmanResources.createButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, { isRootful: false, setAsDefault: false }); + await delay(5000); await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); - const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); - playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); - }, 150_000); + await playExpect(machineBox.resourceElementConnectionStatus).toHaveText(ResourceElementState.Running); + }); + test('Cleanup', async () => { + test.setTimeout(150000); + await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); + }); }); diff --git a/tests/playwright/src/utility/operations.ts b/tests/playwright/src/utility/operations.ts index a28cf959bbfb1..575745278d461 100644 --- a/tests/playwright/src/utility/operations.ts +++ b/tests/playwright/src/utility/operations.ts @@ -205,18 +205,29 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string if ((await podmanResourceCard.resourceElementConnectionStatus.innerText()) === ResourceElementState.Running) { await podmanResourceCard.performConnectionAction(ResourceElementActions.Stop); await playExpect(podmanResourceCard.resourceElementConnectionStatus).toHaveText(ResourceElementState.Off, { - timeout: 30_000, + timeout: 100_000, }); } - await playExpect(resourcesPodmanConnections.machineDeleteButton).toBeVisible({ timeout: 3000 }); - await waitWhile(() => resourcesPodmanConnections.machineDeleteButton.isDisabled(), { timeout: 10000 }); - await resourcesPodmanConnections.machineDeleteButton.click(); - await playExpect(resourcesPodmanConnections.podmanMachineElement).toBeHidden({ timeout: 60_000 }); + await podmanResourceCard.performConnectionAction(ResourceElementActions.Delete); + await playExpect(podmanResourceCard.resourceElement).toBeHidden({ timeout: 30_000 }); + await handleResetDefaultConnectionDialog(page); } else { console.log(`Podman machine [${machineVisibleName}] not present, skipping deletion.`); } } +export async function handleResetDefaultConnectionDialog(page: Page): Promise { + const connectionDialog = page.getByRole('dialog', { name: 'Podman' }); + if (await connectionDialog.isVisible()) { + const handleButton = connectionDialog.getByRole('button', { name: 'Yes' }); + await handleButton.click(); + + await playExpect(connectionDialog).toBeVisible(); + const okButton = connectionDialog.getByRole('button', { name: 'OK' }); + await okButton.click(); + } +} + export async function getVolumeNameForContainer(page: Page, containerName: string): Promise { try { const navigationBar = new NavigationBar(page); From f36c1dc4884a551be7cb3e71d100c3ad519f2f53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tamara=20Bab=C3=A1lov=C3=A1?= Date: Thu, 5 Sep 2024 03:04:00 -0700 Subject: [PATCH 11/53] =?UTF-8?q?chore(tests):=20refactoring=20for=20fixtu?= =?UTF-8?q?res=20Signed-off-by:=20Tamara=20Bab=C3=A1lov=C3=A1=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/model/pages/create-machine-page.ts | 41 ++++++++----------- .../src/specs/podman-machine-rootless.spec.ts | 40 +++++------------- tests/playwright/src/utility/operations.ts | 32 ++++++++------- 3 files changed, 47 insertions(+), 66 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 8d6167b33dceb..82fae49ef1357 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -19,8 +19,6 @@ import type { Locator, Page } from '@playwright/test'; import { expect as playExpect } from '@playwright/test'; -import { delay } from '/@/utility/wait'; - import { BasePage } from './base-page'; import { ResourcesPage } from './resources-page'; @@ -66,22 +64,22 @@ export class CreateMachinePage extends BasePage { machineName: string, { isRootful = true, enableUserNet = false, startNow = true, setAsDefault = true }, ): Promise { - await playExpect(this.podmanMachineConfiguration).toBeVisible(); + await playExpect(this.podmanMachineConfiguration).toBeVisible({ timeout: 10_000 }); + await this.podmanMachineName.clear(); await this.podmanMachineName.fill(machineName); await this.ensureCheckboxState(isRootful, this.rootPriviledgesCheckbox); await this.ensureCheckboxState(enableUserNet, this.userModeNetworkingCheckbox); await this.ensureCheckboxState(startNow, this.startNowCheckbox); + await playExpect(this.createMachineButton).toBeEnabled(); await this.createMachineButton.click(); - await this.page.waitForTimeout(60_000); - - const successfulCreationMessage = this.page.getByText('Successful operation'); - const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await delay(5000); + // wait for machine creation and handle connections await this.handleConnectionDialog(machineName, setAsDefault); + const successfulCreationMessage = this.page.getByText('Successful operation'); + const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10_000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); @@ -107,31 +105,28 @@ export class CreateMachinePage extends BasePage { const upperElement = checkbox.locator('..').locator('..'); const wasEnabled = await this.isEnabled(checkbox); - let checkText; - if (wasEnabled) { - checkText = 'Enabled'; - } else { - checkText = 'Disabled'; - } + const checkText = wasEnabled ? 'Enabled' : 'Disabled'; + const switchedStatus = wasEnabled ? 'Disabled' : 'Enabled'; const clickableCheckbox = upperElement.getByText(checkText); await clickableCheckbox.click(); + + await playExpect(upperElement).toHaveText(switchedStatus); } async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise { const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); - const dialogMessage = connectionDialog.getByText( + await playExpect(connectionDialog).toBeVisible({ timeout: 60_000 }); + + const dialogMessage = connectionDialog.getByLabel('Dialog Message'); + await playExpect(dialogMessage).toHaveText( new RegExp( `Podman Machine '${machineName}' is running but not the default machine .+ Do you want to set it as default?`, ), ); - if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) { - let handleButtonName = 'Yes'; - if (!setAsDefault) { - handleButtonName = 'Ignore'; - } - const handleButton = connectionDialog.getByRole('button', { name: handleButtonName }); - await handleButton.click(); - } + + const handleButtonName = setAsDefault ? 'Yes' : 'Ignore'; + const handleButton = connectionDialog.getByRole('button', { name: handleButtonName }); + await handleButton.click(); } } diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 4bf7215c79c5e..85a853b73598c 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -17,60 +17,42 @@ ***********************************************************************/ import * as os from 'node:os'; -import type { Page } from '@playwright/test'; -import { expect as playExpect, test } from '@playwright/test'; - import { ResourceElementState } from '../model/core/states'; import { CreateMachinePage } from '../model/pages/create-machine-page'; import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; -import { WelcomePage } from '../model/pages/welcome-page'; -import { NavigationBar } from '../model/workbench/navigation'; -import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; +import { expect as playExpect, test } from '../utility/fixtures'; import { deletePodmanMachine } from '../utility/operations'; -import { delay } from '../utility/wait'; -let pdRunner: PodmanDesktopRunner; -let page: Page; -let navBar: NavigationBar; const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; -const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; -test.beforeAll(async () => { - pdRunner = new PodmanDesktopRunner(); - page = await pdRunner.start(); +test.beforeAll(async ({ pdRunner, welcomePage }) => { pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); process.env.KEEP_TRACES_ON_PASS = 'true'; - const welcomePage = new WelcomePage(page); await welcomePage.handleWelcomePage(true); - navBar = new NavigationBar(page); }); -test.afterAll(async () => { +test.afterAll(async ({ pdRunner }) => { await pdRunner.close(); }); +test.skip(os.platform() === 'linux', 'Runs only on Windows and Mac'); test.describe('Rootless Podman machine Verification', () => { - test.skip(os.platform() === 'linux', 'runs only on windows and mac'); - - test('Create a rootless machine', async () => { - test.setTimeout(200000); + test('Create a rootless machine', async ({ page, navigationBar }) => { + test.setTimeout(200_000); - await navBar.openSettings(); + await navigationBar.openSettings(); const podmanResources = new ResourceConnectionCardPage(page, 'podman'); - await podmanResources.createButton.click(); const createMachinePage = new CreateMachinePage(page); await createMachinePage.createMachine(PODMAN_MACHINE_NAME, { isRootful: false, setAsDefault: false }); - await delay(5000); - await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); - const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); + const machineBox = new ResourceConnectionCardPage(page, 'podman', PODMAN_MACHINE_NAME); //does not work with visible name await playExpect(machineBox.resourceElementConnectionStatus).toHaveText(ResourceElementState.Running); }); - test('Cleanup', async () => { - test.setTimeout(150000); - await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); + test('Clean up rootless machine', async ({ page }) => { + test.setTimeout(150_000); + await deletePodmanMachine(page, PODMAN_MACHINE_NAME); }); }); diff --git a/tests/playwright/src/utility/operations.ts b/tests/playwright/src/utility/operations.ts index 575745278d461..31cc30ef0b0b4 100644 --- a/tests/playwright/src/utility/operations.ts +++ b/tests/playwright/src/utility/operations.ts @@ -57,7 +57,7 @@ export async function deleteContainer(page: Page, name: string): Promise { // wait for container to disappear try { console.log('Waiting for container to get deleted ...'); - await playExpect.poll(async () => await containers.getContainerRowByName(name), { timeout: 10_000 }).toBeFalsy(); + await playExpect.poll(async () => await containers.getContainerRowByName(name), { timeout: 30_000 }).toBeFalsy(); } catch (error) { if (!(error as Error).message.includes('Page is empty')) { throw Error(`Error waiting for container '${name}' to get removed, ${error}`); @@ -210,7 +210,11 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string } await podmanResourceCard.performConnectionAction(ResourceElementActions.Delete); await playExpect(podmanResourceCard.resourceElement).toBeHidden({ timeout: 30_000 }); - await handleResetDefaultConnectionDialog(page); + + const defaultMachineCard = new ResourceConnectionCardPage(page, RESOURCE_NAME, 'podman-machine-default'); + if (await defaultMachineCard.resourceElement.isVisible()) { + await handleResetDefaultConnectionDialog(page); + } } else { console.log(`Podman machine [${machineVisibleName}] not present, skipping deletion.`); } @@ -218,14 +222,14 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string export async function handleResetDefaultConnectionDialog(page: Page): Promise { const connectionDialog = page.getByRole('dialog', { name: 'Podman' }); - if (await connectionDialog.isVisible()) { - const handleButton = connectionDialog.getByRole('button', { name: 'Yes' }); - await handleButton.click(); + await playExpect(connectionDialog).toBeVisible({ timeout: 20_000 }); - await playExpect(connectionDialog).toBeVisible(); - const okButton = connectionDialog.getByRole('button', { name: 'OK' }); - await okButton.click(); - } + const handleButton = connectionDialog.getByRole('button', { name: 'Yes' }); + await handleButton.click(); + + await playExpect(connectionDialog).toBeVisible(); + const okButton = connectionDialog.getByRole('button', { name: 'OK' }); + await okButton.click(); } export async function getVolumeNameForContainer(page: Page, containerName: string): Promise { @@ -271,7 +275,7 @@ export async function createKindCluster( page: Page, clusterName: string, usedefaultOptions: boolean, - timeout: number = 200000, + timeout: number = 200_000, { providerType, httpPort, httpsPort, useIngressController, containerImage }: KindClusterOptions = {}, ): Promise { const navigationBar = new NavigationBar(page); @@ -302,7 +306,7 @@ export async function createKindCluster( } await playExpect(kindResourceCard.resourceElement).toBeVisible(); await playExpect(kindResourceCard.resourceElementConnectionStatus).toHaveText(ResourceElementState.Running, { - timeout: 15000, + timeout: 15_000, }); await statusBar.validateKubernetesContext(`kind-${clusterName}`); } @@ -317,12 +321,12 @@ export async function deleteKindCluster( await navigationBar.openSettings(); await kindResourceCard.performConnectionAction(ResourceElementActions.Stop); await playExpect(kindResourceCard.resourceElementConnectionStatus).toHaveText(ResourceElementState.Off, { - timeout: 50000, + timeout: 50_000, }); await kindResourceCard.performConnectionAction(ResourceElementActions.Delete); - await playExpect(kindResourceCard.markdownContent).toBeVisible({ timeout: 50000 }); + await playExpect(kindResourceCard.markdownContent).toBeVisible({ timeout: 50_000 }); const containersPage = await navigationBar.openContainers(); - await playExpect.poll(async () => containersPage.containerExists(containerName), { timeout: 10000 }).toBeFalsy(); + await playExpect.poll(async () => containersPage.containerExists(containerName), { timeout: 10_000 }).toBeFalsy(); const volumeName = await getVolumeNameForContainer(page, containerName); await playExpect.poll(async () => volumeName).toBeFalsy(); From c2726539c39c57a74cf0b9aef73e31b1994f1fce Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Fri, 26 Apr 2024 02:15:15 +0200 Subject: [PATCH 12/53] chore(tests): rootless machine creation test added Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 76 +++++++++++++++++++ .../src/specs/podman-machine-rootless.spec.ts | 74 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 tests/playwright/src/model/pages/create-machine-page.ts create mode 100644 tests/playwright/src/specs/podman-machine-rootless.spec.ts diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts new file mode 100644 index 0000000000000..1c3eef3d295f5 --- /dev/null +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -0,0 +1,76 @@ +/********************************************************************** + * Copyright (C) 2023 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 { expect as playExpect } from '@playwright/test'; + +import { BasePage } from './base-page'; +import { ResourcesPage } from './resources-page'; + +export class CreateMachinePage extends BasePage { + readonly heading: Locator; + readonly machineNameBox: Locator; + readonly cpuSlider: Locator; + readonly memorySlider: Locator; + readonly diskSlider: Locator; + readonly imagePathBox: Locator; + readonly browseImagesButton: Locator; + readonly rootPriviledgesCheckbox: Locator; + readonly userModeNetworkingCheckbox: Locator; + readonly startNowCheckbox: Locator; + readonly closeButton: Locator; + readonly createMachineButton: Locator; + + constructor(page: Page) { + super(page); + this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); + this.machineNameBox = this.page.getByRole('textbox', { name: 'Name' }); + this.cpuSlider = this.page.getByRole('slider', { name: 'CPU(s)' }); + this.memorySlider = this.page.getByRole('slider', { name: 'Memory' }); + this.diskSlider = this.page.getByRole('slider', { name: 'Disk size' }); + this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); + this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); + this.rootPriviledgesCheckbox = this.page.getByRole('checkbox', { name: 'Machine with root priviledges' }); + this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { + name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', + }); + this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); + this.closeButton = this.page.getByRole('button', { name: 'Close page' }); + this.createMachineButton = this.page.getByRole('button', { name: 'Create Pod' }); + } + + async createMachine(machineName: string, isRootless: boolean): Promise { + //can be extended + await this.machineNameBox.fill(machineName); + if (!isRootless) { + await this.rootPriviledgesCheckbox.uncheck(); + playExpect(this.rootPriviledgesCheckbox.isChecked()).toBeFalsy(); + } + + await this.createMachineButton.click(); + + const successfulCreationMessage = this.page.getByLabel('Successful operation'); + const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); + + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 50000 }); + await playExpect(goBackToResourcesButton).toBeVisible(); + await goBackToResourcesButton.click(); + + return new ResourcesPage(this.page); + } +} diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts new file mode 100644 index 0000000000000..692626c067f64 --- /dev/null +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -0,0 +1,74 @@ +/********************************************************************** + * 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 { expect as playExpect } from '@playwright/test'; +import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; + +import { CreateMachinePage } from '../model/pages/create-machine-page'; +import { ResourcesPage } from '../model/pages/resources-page'; +import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page'; +import { WelcomePage } from '../model/pages/welcome-page'; +import { NavigationBar } from '../model/workbench/navigation'; +import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; +import type { RunnerTestContext } from '../testContext/runner-test-context'; +import { deletePodmanMachine } from '../utility/operations'; + +let pdRunner: PodmanDesktopRunner; +let page: Page; +let navBar: NavigationBar; +const PODMAN_MACHINE_NAME: string = 'Podman Machine Rootless'; + +beforeAll(async () => { + pdRunner = new PodmanDesktopRunner(); + page = await pdRunner.start(); + pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); + + const welcomePage = new WelcomePage(page); + await welcomePage.handleWelcomePage(true); + navBar = new NavigationBar(page); +}); + +afterAll(async () => { + await deletePodmanMachine(page, PODMAN_MACHINE_NAME); + await pdRunner.close(); +}); + +beforeEach(async ctx => { + ctx.pdRunner = pdRunner; +}); + +describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { + test('Create a rootless machine', async () => { + await navBar.openSettings(); + const resourcesPage = new ResourcesPage(page); + + const createMachineButton = resourcesPage.podmanResources.getByRole('button', { + name: 'Create new Podman machine', + }); + await createMachineButton.click(); + + const createMachinePage = new CreateMachinePage(page); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); + + const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); + const connectionStatus = await machineBox.machineConnectionStatus.allTextContents(); + playExpect(connectionStatus[0] === 'RUNNING').toBeTruthy(); + }); +}); From 091460f5d386c6deb233c31e2d41398cd6ebfd69 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 13/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 34 ++++++++++--------- .../src/specs/podman-machine-rootless.spec.ts | 8 +++-- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 1c3eef3d295f5..472c6af4a9551 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. @@ -25,9 +25,7 @@ import { ResourcesPage } from './resources-page'; export class CreateMachinePage extends BasePage { readonly heading: Locator; readonly machineNameBox: Locator; - readonly cpuSlider: Locator; - readonly memorySlider: Locator; - readonly diskSlider: Locator; + readonly podmanMachineConfiguration: Locator; readonly imagePathBox: Locator; readonly browseImagesButton: Locator; readonly rootPriviledgesCheckbox: Locator; @@ -39,35 +37,39 @@ export class CreateMachinePage extends BasePage { constructor(page: Page) { super(page); this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); - this.machineNameBox = this.page.getByRole('textbox', { name: 'Name' }); - this.cpuSlider = this.page.getByRole('slider', { name: 'CPU(s)' }); - this.memorySlider = this.page.getByRole('slider', { name: 'Memory' }); - this.diskSlider = this.page.getByRole('slider', { name: 'Disk size' }); + this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); + + this.machineNameBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); - this.rootPriviledgesCheckbox = this.page.getByRole('checkbox', { name: 'Machine with root priviledges' }); + this.rootPriviledgesCheckbox = this.podmanMachineConfiguration + .getByRole('checkbox', { name: 'Machine with root privileges' }) + .locator('..'); this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', }); this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); - this.closeButton = this.page.getByRole('button', { name: 'Close page' }); - this.createMachineButton = this.page.getByRole('button', { name: 'Create Pod' }); + this.closeButton = this.page.getByRole('button', { name: 'Close' }); + this.createMachineButton = this.page.getByRole('button', { name: 'Create' }); } async createMachine(machineName: string, isRootless: boolean): Promise { - //can be extended + await playExpect(this.podmanMachineConfiguration).toBeVisible(); await this.machineNameBox.fill(machineName); + if (!isRootless) { - await this.rootPriviledgesCheckbox.uncheck(); - playExpect(this.rootPriviledgesCheckbox.isChecked()).toBeFalsy(); + await playExpect(this.rootPriviledgesCheckbox).toBeVisible(); + const upperElement = this.rootPriviledgesCheckbox.locator('..'); + const clickableCheckbox = upperElement.getByText('Enable'); + await clickableCheckbox.click(); } await this.createMachineButton.click(); - const successfulCreationMessage = this.page.getByLabel('Successful operation'); + const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 50000 }); + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 100000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 692626c067f64..22b59ea99d581 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -68,7 +68,9 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); - const connectionStatus = await machineBox.machineConnectionStatus.allTextContents(); - playExpect(connectionStatus[0] === 'RUNNING').toBeTruthy(); - }); + const connectionStatusLabel = await machineBox.machineConnectionStatus + .getByLabel('Connection Status Label') + .textContent(); + playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); + }, 150000); }); From d5b47f02aa9774c6620582f399de8c0e9b8bc763 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 14/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 72 ++++++++++++++----- .../src/specs/podman-machine-rootless.spec.ts | 11 ++- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 472c6af4a9551..2000d3e86dd98 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. @@ -24,10 +24,13 @@ import { ResourcesPage } from './resources-page'; export class CreateMachinePage extends BasePage { readonly heading: Locator; - readonly machineNameBox: Locator; + readonly podmanMachineName: Locator; readonly podmanMachineConfiguration: Locator; readonly imagePathBox: Locator; readonly browseImagesButton: Locator; + readonly podmanMachineCPUs: Locator; + readonly podmanMachineMemory: Locator; + readonly podmanMachineDiskSize: Locator; readonly rootPriviledgesCheckbox: Locator; readonly userModeNetworkingCheckbox: Locator; readonly startNowCheckbox: Locator; @@ -38,30 +41,42 @@ export class CreateMachinePage extends BasePage { super(page); this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); - - this.machineNameBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); + this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); - this.rootPriviledgesCheckbox = this.podmanMachineConfiguration - .getByRole('checkbox', { name: 'Machine with root privileges' }) - .locator('..'); - this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { - name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', + 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.rootPriviledgesCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'Machine with root privileges', + }); + this.userModeNetworkingCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'User mode networking', }); - this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); + this.startNowCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { name: 'Start the machine now' }); this.closeButton = this.page.getByRole('button', { name: 'Close' }); this.createMachineButton = this.page.getByRole('button', { name: 'Create' }); } - async createMachine(machineName: string, isRootless: boolean): Promise { + async createMachine( + machineName: string, + isRootful: boolean = true, + enableUserNet: boolean = false, + startNow: boolean = true, + ): Promise { await playExpect(this.podmanMachineConfiguration).toBeVisible(); - await this.machineNameBox.fill(machineName); + await this.podmanMachineName.fill(machineName); + + if (isRootful !== (await this.isEnabled(this.rootPriviledgesCheckbox))) { + await this.switchCheckbox(this.rootPriviledgesCheckbox); + } - if (!isRootless) { - await playExpect(this.rootPriviledgesCheckbox).toBeVisible(); - const upperElement = this.rootPriviledgesCheckbox.locator('..'); - const clickableCheckbox = upperElement.getByText('Enable'); - await clickableCheckbox.click(); + if (enableUserNet !== (await this.isEnabled(this.userModeNetworkingCheckbox))) { + await this.switchCheckbox(this.userModeNetworkingCheckbox); + } + + if (startNow !== (await this.isEnabled(this.startNowCheckbox))) { + await this.switchCheckbox(this.startNowCheckbox); } await this.createMachineButton.click(); @@ -75,4 +90,27 @@ export class CreateMachinePage extends BasePage { return new ResourcesPage(this.page); } + + async isEnabled(checkbox: Locator): Promise { + await playExpect(checkbox).toBeVisible(); + const upperElement = checkbox.locator('..').locator('..'); + const clickableCheckbox = upperElement.getByText('Enabled'); + return await clickableCheckbox.isVisible(); + } + + async switchCheckbox(checkbox: Locator): Promise { + await playExpect(checkbox).toBeVisible(); + const upperElement = checkbox.locator('..').locator('..'); + + const wasEnabled = await this.isEnabled(checkbox); + let checkText; + if (wasEnabled) { + checkText = 'Enabled'; + } else { + checkText = 'Disabled'; + } + + const clickableCheckbox = upperElement.getByText(checkText); + await clickableCheckbox.click(); + } } diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 22b59ea99d581..522b592fbc8dc 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -33,7 +33,8 @@ import { deletePodmanMachine } from '../utility/operations'; let pdRunner: PodmanDesktopRunner; let page: Page; let navBar: NavigationBar; -const PODMAN_MACHINE_NAME: string = 'Podman Machine Rootless'; +const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; +const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); @@ -65,12 +66,10 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true); - const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); - const connectionStatusLabel = await machineBox.machineConnectionStatus - .getByLabel('Connection Status Label') - .textContent(); + const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); + const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); }, 150000); }); From b94db6ff450d4a49c14b01160a15e8653e7b1c03 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 9 Jul 2024 08:01:56 +0200 Subject: [PATCH 15/53] chore(tests): addressing changes 2 Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 2000d3e86dd98..02bb2c71aaf3d 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -42,8 +42,10 @@ export class CreateMachinePage extends BasePage { this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); - this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); - this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); + this.imagePathBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Image Path (Optional) ' }); + this.browseImagesButton = this.podmanMachineConfiguration.getByRole('button', { + name: 'button-Image Path (Optional)', + }); 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' }); From 3fd158c2d108ada3814afda3b81c300f164847ba Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 6 Aug 2024 00:21:13 +0200 Subject: [PATCH 16/53] chore(tests): added connection dialog handling Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 25 ++++++++++++++++++- .../src/specs/podman-machine-rootless.spec.ts | 6 +++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 02bb2c71aaf3d..e055a7e2f11fa 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -65,6 +65,7 @@ export class CreateMachinePage extends BasePage { isRootful: boolean = true, enableUserNet: boolean = false, startNow: boolean = true, + setAsDefault: boolean = true, ): Promise { await playExpect(this.podmanMachineConfiguration).toBeVisible(); await this.podmanMachineName.fill(machineName); @@ -82,11 +83,14 @@ export class CreateMachinePage extends BasePage { } await this.createMachineButton.click(); + await this.page.waitForTimeout(60000); const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 100000 }); + await this.handleConnectionDialog(machineName, setAsDefault); + + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); @@ -115,4 +119,23 @@ export class CreateMachinePage extends BasePage { const clickableCheckbox = upperElement.getByText(checkText); await clickableCheckbox.click(); } + + async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise { + const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); + const dialogMessage = connectionDialog.getByText( + new RegExp( + "Podman Machine '" + + machineName + + "' is running but not the default machine .+ Do you want to set it as default?", + ), + ); + if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) { + let handleButtonName = 'Yes'; + if (!setAsDefault) { + handleButtonName = 'Ignore'; + } + const handleButton = connectionDialog.getByRole('button', { name: handleButtonName }); + await handleButton.click(); + } + } } diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 522b592fbc8dc..c9cde379e53b7 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -40,6 +40,7 @@ beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); page = await pdRunner.start(); pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); + process.env.KEEP_TRACES_ON_PASS = 'true'; const welcomePage = new WelcomePage(page); await welcomePage.handleWelcomePage(true); @@ -47,7 +48,7 @@ beforeAll(async () => { }); afterAll(async () => { - await deletePodmanMachine(page, PODMAN_MACHINE_NAME); + await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); await pdRunner.close(); }); @@ -66,7 +67,8 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); + await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); From 20d1ebc58cb426283ed2737f331ea5cbaf7c5801 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 17/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index e055a7e2f11fa..69569aadd347a 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. From 76d3469e7de43ba8bd49c9938e358fd0bf48ce18 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 18/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 69569aadd347a..e055a7e2f11fa 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. From f4af3f76f8cc2c1f7b7ca3ebfa743015c7026c85 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Thu, 8 Aug 2024 09:50:11 +0200 Subject: [PATCH 19/53] chore(tests): solving conflicts Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 4 +--- .../src/specs/podman-machine-rootless.spec.ts | 14 +++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index e055a7e2f11fa..6e91247b7ed69 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -124,9 +124,7 @@ export class CreateMachinePage extends BasePage { const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); const dialogMessage = connectionDialog.getByText( new RegExp( - "Podman Machine '" + - machineName + - "' is running but not the default machine .+ Do you want to set it as default?", + `Podman Machine '${machineName}' is running but not the default machine .+ Do you want to set it as default?`, ), ); if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) { diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index c9cde379e53b7..ff5b6c9d70c57 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -22,8 +22,7 @@ import { expect as playExpect } from '@playwright/test'; import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; import { CreateMachinePage } from '../model/pages/create-machine-page'; -import { ResourcesPage } from '../model/pages/resources-page'; -import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page'; +import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; import { WelcomePage } from '../model/pages/welcome-page'; import { NavigationBar } from '../model/workbench/navigation'; import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; @@ -59,19 +58,16 @@ beforeEach(async ctx => { describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { test('Create a rootless machine', async () => { await navBar.openSettings(); - const resourcesPage = new ResourcesPage(page); + const podmanResources = new ResourceConnectionCardPage(page, 'podman'); - const createMachineButton = resourcesPage.podmanResources.getByRole('button', { - name: 'Create new Podman machine', - }); - await createMachineButton.click(); + await podmanResources.createButton.click(); const createMachinePage = new CreateMachinePage(page); await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); - const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); - const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); + const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); + const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); }, 150000); }); From a94edc1f9d34d29e0c09b5a020e86095a84ddb70 Mon Sep 17 00:00:00 2001 From: xbabalov Date: Mon, 19 Aug 2024 22:24:22 +0200 Subject: [PATCH 20/53] chore(tests): number refactoring Signed-off-by: xbabalov --- tests/playwright/src/model/pages/create-machine-page.ts | 4 ++-- tests/playwright/src/specs/podman-machine-rootless.spec.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 6e91247b7ed69..2270bd19b379d 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -83,14 +83,14 @@ export class CreateMachinePage extends BasePage { } await this.createMachineButton.click(); - await this.page.waitForTimeout(60000); + await this.page.waitForTimeout(60_000); const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); await this.handleConnectionDialog(machineName, setAsDefault); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10000 }); + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10_000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index ff5b6c9d70c57..f1c1b853f26b4 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -69,5 +69,5 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); - }, 150000); + }, 150_000); }); From 8c6680c46f9cda12630f11a4c597d8b1087c9f83 Mon Sep 17 00:00:00 2001 From: xbabalov Date: Tue, 24 Sep 2024 01:00:04 +0200 Subject: [PATCH 21/53] chore(tests): machine create form refactoring Signed-off-by: xbabalov --- .../src/model/pages/create-machine-page.ts | 72 ++--------------- .../pages/forms/machine-creation-form.ts | 79 +++++++++++++++++++ tests/playwright/src/utility/operations.ts | 17 ++++ 3 files changed, 102 insertions(+), 66 deletions(-) create mode 100644 tests/playwright/src/model/pages/forms/machine-creation-form.ts diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 2270bd19b379d..3ef41766cd546 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -20,67 +20,30 @@ import type { Locator, Page } from '@playwright/test'; import { expect as playExpect } from '@playwright/test'; import { BasePage } from './base-page'; +import { MachineCreationForm } from './forms/machine-creation-form'; import { ResourcesPage } from './resources-page'; export class CreateMachinePage extends BasePage { readonly heading: Locator; - readonly podmanMachineName: Locator; - readonly podmanMachineConfiguration: Locator; - readonly imagePathBox: Locator; - readonly browseImagesButton: Locator; - readonly podmanMachineCPUs: Locator; - readonly podmanMachineMemory: Locator; - readonly podmanMachineDiskSize: Locator; - readonly rootPriviledgesCheckbox: Locator; - readonly userModeNetworkingCheckbox: Locator; - readonly startNowCheckbox: Locator; readonly closeButton: Locator; readonly createMachineButton: Locator; constructor(page: Page) { super(page); this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); - this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); - this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); - this.imagePathBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Image Path (Optional) ' }); - this.browseImagesButton = this.podmanMachineConfiguration.getByRole('button', { - name: 'button-Image Path (Optional)', - }); - 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.rootPriviledgesCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { - name: 'Machine with root privileges', - }); - this.userModeNetworkingCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { - name: 'User mode networking', - }); - this.startNowCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { name: 'Start the machine now' }); this.closeButton = this.page.getByRole('button', { name: 'Close' }); this.createMachineButton = this.page.getByRole('button', { name: 'Create' }); } async createMachine( machineName: string, - isRootful: boolean = true, - enableUserNet: boolean = false, - startNow: boolean = true, + isRootful?: boolean, + enableUserNet?: boolean, + startNow?: boolean, setAsDefault: boolean = true, ): Promise { - await playExpect(this.podmanMachineConfiguration).toBeVisible(); - await this.podmanMachineName.fill(machineName); - - if (isRootful !== (await this.isEnabled(this.rootPriviledgesCheckbox))) { - await this.switchCheckbox(this.rootPriviledgesCheckbox); - } - - if (enableUserNet !== (await this.isEnabled(this.userModeNetworkingCheckbox))) { - await this.switchCheckbox(this.userModeNetworkingCheckbox); - } - - if (startNow !== (await this.isEnabled(this.startNowCheckbox))) { - await this.switchCheckbox(this.startNowCheckbox); - } + const machineCreationForm = new MachineCreationForm(this.page); + await machineCreationForm.configureMachine(machineName, isRootful, enableUserNet, startNow); await this.createMachineButton.click(); await this.page.waitForTimeout(60_000); @@ -97,29 +60,6 @@ export class CreateMachinePage extends BasePage { return new ResourcesPage(this.page); } - async isEnabled(checkbox: Locator): Promise { - await playExpect(checkbox).toBeVisible(); - const upperElement = checkbox.locator('..').locator('..'); - const clickableCheckbox = upperElement.getByText('Enabled'); - return await clickableCheckbox.isVisible(); - } - - async switchCheckbox(checkbox: Locator): Promise { - await playExpect(checkbox).toBeVisible(); - const upperElement = checkbox.locator('..').locator('..'); - - const wasEnabled = await this.isEnabled(checkbox); - let checkText; - if (wasEnabled) { - checkText = 'Enabled'; - } else { - checkText = 'Disabled'; - } - - const clickableCheckbox = upperElement.getByText(checkText); - await clickableCheckbox.click(); - } - async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise { const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); const dialogMessage = connectionDialog.getByText( diff --git a/tests/playwright/src/model/pages/forms/machine-creation-form.ts b/tests/playwright/src/model/pages/forms/machine-creation-form.ts new file mode 100644 index 0000000000000..799144fe19892 --- /dev/null +++ b/tests/playwright/src/model/pages/forms/machine-creation-form.ts @@ -0,0 +1,79 @@ +/********************************************************************** + * 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 { expect as playExpect, Locator, Page } from '@playwright/test'; + +import { BasePage } from '../base-page'; + +export class MachineCreationForm extends BasePage { + readonly podmanMachineConfiguration: Locator; + readonly podmanMachineName: Locator; + readonly imagePathBox: Locator; + readonly browseImagesButton: Locator; + readonly podmanMachineCPUs: Locator; + readonly podmanMachineMemory: Locator; + readonly podmanMachineDiskSize: Locator; + readonly rootPriviledgesCheckbox: Locator; + readonly userModeNetworkingCheckbox: Locator; + readonly startNowCheckbox: Locator; + + constructor(page: Page) { + super(page); + this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); + this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); + this.imagePathBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Image Path (Optional) ' }); + this.browseImagesButton = this.podmanMachineConfiguration.getByRole('button', { + name: 'button-Image Path (Optional)', + }); + 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.rootPriviledgesCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'Machine with root privileges', + }); + this.userModeNetworkingCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'User mode networking', + }); + this.startNowCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { name: 'Start the machine now' }); + } + + async configureMachine( + machineName: string, + isRootful: boolean = true, + enableUserNet: boolean = false, + startNow: boolean = true, + ): Promise { + await playExpect(this.podmanMachineConfiguration).toBeVisible(); + await this.podmanMachineName.fill(machineName); + + if (isRootful !== (await this.rootPriviledgesCheckbox.isChecked())) { + await this.rootPriviledgesCheckbox.locator('..').click(); + playExpect(await this.rootPriviledgesCheckbox.isChecked()).toBe(isRootful); + } + + if (enableUserNet !== (await this.userModeNetworkingCheckbox.isChecked())) { + await this.userModeNetworkingCheckbox.locator('..').click(); + playExpect(await this.userModeNetworkingCheckbox.isChecked()).toBe(enableUserNet); + } + + if (startNow !== (await this.startNowCheckbox.isChecked())) { + await this.startNowCheckbox.locator('..').click(); + playExpect(await this.startNowCheckbox.isChecked()).toBe(startNow); + } + } +} diff --git a/tests/playwright/src/utility/operations.ts b/tests/playwright/src/utility/operations.ts index 9d2fe0dd89f98..fb9b3ede70bd2 100644 --- a/tests/playwright/src/utility/operations.ts +++ b/tests/playwright/src/utility/operations.ts @@ -234,12 +234,29 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string } await podmanResourceCard.performConnectionAction(ResourceElementActions.Delete); await playExpect(podmanResourceCard.resourceElement).toBeHidden({ timeout: 60_000 }); + + const defaultMachineCard = new ResourceConnectionCardPage(page, RESOURCE_NAME, 'podman-machine-default'); + if (await defaultMachineCard.resourceElement.isVisible()) { + await handleResetDefaultConnectionDialog(page); + } } else { console.log(`Podman machine [${machineVisibleName}] not present, skipping deletion.`); } }); } +export async function handleResetDefaultConnectionDialog(page: Page): Promise { + const connectionDialog = page.getByRole('dialog', { name: 'Podman' }); + await playExpect(connectionDialog).toBeVisible({ timeout: 20_000 }); + + const handleButton = connectionDialog.getByRole('button', { name: 'Yes' }); + await handleButton.click(); + + await playExpect(connectionDialog).toBeVisible(); + const okButton = connectionDialog.getByRole('button', { name: 'OK' }); + await okButton.click(); +} + export async function getVolumeNameForContainer(page: Page, containerName: string): Promise { return await test.step('Get volume name for container', async () => { let volumeName; From a137835a98be205163c3d88faa6a474291870c08 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Fri, 26 Apr 2024 02:15:15 +0200 Subject: [PATCH 22/53] chore(tests): rootless machine creation test added Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 76 +++++++++++++++++++ .../src/specs/podman-machine-rootless.spec.ts | 74 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 tests/playwright/src/model/pages/create-machine-page.ts create mode 100644 tests/playwright/src/specs/podman-machine-rootless.spec.ts diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts new file mode 100644 index 0000000000000..1c3eef3d295f5 --- /dev/null +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -0,0 +1,76 @@ +/********************************************************************** + * Copyright (C) 2023 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 { expect as playExpect } from '@playwright/test'; + +import { BasePage } from './base-page'; +import { ResourcesPage } from './resources-page'; + +export class CreateMachinePage extends BasePage { + readonly heading: Locator; + readonly machineNameBox: Locator; + readonly cpuSlider: Locator; + readonly memorySlider: Locator; + readonly diskSlider: Locator; + readonly imagePathBox: Locator; + readonly browseImagesButton: Locator; + readonly rootPriviledgesCheckbox: Locator; + readonly userModeNetworkingCheckbox: Locator; + readonly startNowCheckbox: Locator; + readonly closeButton: Locator; + readonly createMachineButton: Locator; + + constructor(page: Page) { + super(page); + this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); + this.machineNameBox = this.page.getByRole('textbox', { name: 'Name' }); + this.cpuSlider = this.page.getByRole('slider', { name: 'CPU(s)' }); + this.memorySlider = this.page.getByRole('slider', { name: 'Memory' }); + this.diskSlider = this.page.getByRole('slider', { name: 'Disk size' }); + this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); + this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); + this.rootPriviledgesCheckbox = this.page.getByRole('checkbox', { name: 'Machine with root priviledges' }); + this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { + name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', + }); + this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); + this.closeButton = this.page.getByRole('button', { name: 'Close page' }); + this.createMachineButton = this.page.getByRole('button', { name: 'Create Pod' }); + } + + async createMachine(machineName: string, isRootless: boolean): Promise { + //can be extended + await this.machineNameBox.fill(machineName); + if (!isRootless) { + await this.rootPriviledgesCheckbox.uncheck(); + playExpect(this.rootPriviledgesCheckbox.isChecked()).toBeFalsy(); + } + + await this.createMachineButton.click(); + + const successfulCreationMessage = this.page.getByLabel('Successful operation'); + const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); + + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 50000 }); + await playExpect(goBackToResourcesButton).toBeVisible(); + await goBackToResourcesButton.click(); + + return new ResourcesPage(this.page); + } +} diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts new file mode 100644 index 0000000000000..692626c067f64 --- /dev/null +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -0,0 +1,74 @@ +/********************************************************************** + * 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 { expect as playExpect } from '@playwright/test'; +import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; + +import { CreateMachinePage } from '../model/pages/create-machine-page'; +import { ResourcesPage } from '../model/pages/resources-page'; +import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page'; +import { WelcomePage } from '../model/pages/welcome-page'; +import { NavigationBar } from '../model/workbench/navigation'; +import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; +import type { RunnerTestContext } from '../testContext/runner-test-context'; +import { deletePodmanMachine } from '../utility/operations'; + +let pdRunner: PodmanDesktopRunner; +let page: Page; +let navBar: NavigationBar; +const PODMAN_MACHINE_NAME: string = 'Podman Machine Rootless'; + +beforeAll(async () => { + pdRunner = new PodmanDesktopRunner(); + page = await pdRunner.start(); + pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); + + const welcomePage = new WelcomePage(page); + await welcomePage.handleWelcomePage(true); + navBar = new NavigationBar(page); +}); + +afterAll(async () => { + await deletePodmanMachine(page, PODMAN_MACHINE_NAME); + await pdRunner.close(); +}); + +beforeEach(async ctx => { + ctx.pdRunner = pdRunner; +}); + +describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { + test('Create a rootless machine', async () => { + await navBar.openSettings(); + const resourcesPage = new ResourcesPage(page); + + const createMachineButton = resourcesPage.podmanResources.getByRole('button', { + name: 'Create new Podman machine', + }); + await createMachineButton.click(); + + const createMachinePage = new CreateMachinePage(page); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); + + const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); + const connectionStatus = await machineBox.machineConnectionStatus.allTextContents(); + playExpect(connectionStatus[0] === 'RUNNING').toBeTruthy(); + }); +}); From ef1d1390e06e0999996d7cdfd288a6009f43ff24 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 23/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 34 ++++++++++--------- .../src/specs/podman-machine-rootless.spec.ts | 8 +++-- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 1c3eef3d295f5..472c6af4a9551 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. @@ -25,9 +25,7 @@ import { ResourcesPage } from './resources-page'; export class CreateMachinePage extends BasePage { readonly heading: Locator; readonly machineNameBox: Locator; - readonly cpuSlider: Locator; - readonly memorySlider: Locator; - readonly diskSlider: Locator; + readonly podmanMachineConfiguration: Locator; readonly imagePathBox: Locator; readonly browseImagesButton: Locator; readonly rootPriviledgesCheckbox: Locator; @@ -39,35 +37,39 @@ export class CreateMachinePage extends BasePage { constructor(page: Page) { super(page); this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); - this.machineNameBox = this.page.getByRole('textbox', { name: 'Name' }); - this.cpuSlider = this.page.getByRole('slider', { name: 'CPU(s)' }); - this.memorySlider = this.page.getByRole('slider', { name: 'Memory' }); - this.diskSlider = this.page.getByRole('slider', { name: 'Disk size' }); + this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); + + this.machineNameBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); - this.rootPriviledgesCheckbox = this.page.getByRole('checkbox', { name: 'Machine with root priviledges' }); + this.rootPriviledgesCheckbox = this.podmanMachineConfiguration + .getByRole('checkbox', { name: 'Machine with root privileges' }) + .locator('..'); this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', }); this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); - this.closeButton = this.page.getByRole('button', { name: 'Close page' }); - this.createMachineButton = this.page.getByRole('button', { name: 'Create Pod' }); + this.closeButton = this.page.getByRole('button', { name: 'Close' }); + this.createMachineButton = this.page.getByRole('button', { name: 'Create' }); } async createMachine(machineName: string, isRootless: boolean): Promise { - //can be extended + await playExpect(this.podmanMachineConfiguration).toBeVisible(); await this.machineNameBox.fill(machineName); + if (!isRootless) { - await this.rootPriviledgesCheckbox.uncheck(); - playExpect(this.rootPriviledgesCheckbox.isChecked()).toBeFalsy(); + await playExpect(this.rootPriviledgesCheckbox).toBeVisible(); + const upperElement = this.rootPriviledgesCheckbox.locator('..'); + const clickableCheckbox = upperElement.getByText('Enable'); + await clickableCheckbox.click(); } await this.createMachineButton.click(); - const successfulCreationMessage = this.page.getByLabel('Successful operation'); + const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 50000 }); + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 100000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 692626c067f64..22b59ea99d581 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -68,7 +68,9 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); - const connectionStatus = await machineBox.machineConnectionStatus.allTextContents(); - playExpect(connectionStatus[0] === 'RUNNING').toBeTruthy(); - }); + const connectionStatusLabel = await machineBox.machineConnectionStatus + .getByLabel('Connection Status Label') + .textContent(); + playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); + }, 150000); }); From 6ac4c2876e362f799694098d7a71b897bf9b8408 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 24/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 72 ++++++++++++++----- .../src/specs/podman-machine-rootless.spec.ts | 11 ++- 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 472c6af4a9551..2000d3e86dd98 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. @@ -24,10 +24,13 @@ import { ResourcesPage } from './resources-page'; export class CreateMachinePage extends BasePage { readonly heading: Locator; - readonly machineNameBox: Locator; + readonly podmanMachineName: Locator; readonly podmanMachineConfiguration: Locator; readonly imagePathBox: Locator; readonly browseImagesButton: Locator; + readonly podmanMachineCPUs: Locator; + readonly podmanMachineMemory: Locator; + readonly podmanMachineDiskSize: Locator; readonly rootPriviledgesCheckbox: Locator; readonly userModeNetworkingCheckbox: Locator; readonly startNowCheckbox: Locator; @@ -38,30 +41,42 @@ export class CreateMachinePage extends BasePage { super(page); this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); - - this.machineNameBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); + this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); - this.rootPriviledgesCheckbox = this.podmanMachineConfiguration - .getByRole('checkbox', { name: 'Machine with root privileges' }) - .locator('..'); - this.userModeNetworkingCheckbox = this.page.getByRole('checkbox', { - name: 'User mode networking (traffic relayed by a user process). See [documentation](https://docs.podman.io/en/latest/markdown/podman-machine-init.1.html#user-mode-networking).', + 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.rootPriviledgesCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'Machine with root privileges', + }); + this.userModeNetworkingCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'User mode networking', }); - this.startNowCheckbox = this.page.getByRole('checkbox', { name: 'Start the machine now' }); + this.startNowCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { name: 'Start the machine now' }); this.closeButton = this.page.getByRole('button', { name: 'Close' }); this.createMachineButton = this.page.getByRole('button', { name: 'Create' }); } - async createMachine(machineName: string, isRootless: boolean): Promise { + async createMachine( + machineName: string, + isRootful: boolean = true, + enableUserNet: boolean = false, + startNow: boolean = true, + ): Promise { await playExpect(this.podmanMachineConfiguration).toBeVisible(); - await this.machineNameBox.fill(machineName); + await this.podmanMachineName.fill(machineName); + + if (isRootful !== (await this.isEnabled(this.rootPriviledgesCheckbox))) { + await this.switchCheckbox(this.rootPriviledgesCheckbox); + } - if (!isRootless) { - await playExpect(this.rootPriviledgesCheckbox).toBeVisible(); - const upperElement = this.rootPriviledgesCheckbox.locator('..'); - const clickableCheckbox = upperElement.getByText('Enable'); - await clickableCheckbox.click(); + if (enableUserNet !== (await this.isEnabled(this.userModeNetworkingCheckbox))) { + await this.switchCheckbox(this.userModeNetworkingCheckbox); + } + + if (startNow !== (await this.isEnabled(this.startNowCheckbox))) { + await this.switchCheckbox(this.startNowCheckbox); } await this.createMachineButton.click(); @@ -75,4 +90,27 @@ export class CreateMachinePage extends BasePage { return new ResourcesPage(this.page); } + + async isEnabled(checkbox: Locator): Promise { + await playExpect(checkbox).toBeVisible(); + const upperElement = checkbox.locator('..').locator('..'); + const clickableCheckbox = upperElement.getByText('Enabled'); + return await clickableCheckbox.isVisible(); + } + + async switchCheckbox(checkbox: Locator): Promise { + await playExpect(checkbox).toBeVisible(); + const upperElement = checkbox.locator('..').locator('..'); + + const wasEnabled = await this.isEnabled(checkbox); + let checkText; + if (wasEnabled) { + checkText = 'Enabled'; + } else { + checkText = 'Disabled'; + } + + const clickableCheckbox = upperElement.getByText(checkText); + await clickableCheckbox.click(); + } } diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 22b59ea99d581..522b592fbc8dc 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -33,7 +33,8 @@ import { deletePodmanMachine } from '../utility/operations'; let pdRunner: PodmanDesktopRunner; let page: Page; let navBar: NavigationBar; -const PODMAN_MACHINE_NAME: string = 'Podman Machine Rootless'; +const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; +const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); @@ -65,12 +66,10 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true); - const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); - const connectionStatusLabel = await machineBox.machineConnectionStatus - .getByLabel('Connection Status Label') - .textContent(); + const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); + const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); }, 150000); }); From 9215ae69e5816bd050f8f85e0525ab3070df6fa1 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 9 Jul 2024 08:01:56 +0200 Subject: [PATCH 25/53] chore(tests): addressing changes 2 Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 2000d3e86dd98..02bb2c71aaf3d 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -42,8 +42,10 @@ export class CreateMachinePage extends BasePage { this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); - this.imagePathBox = this.page.getByRole('textbox', { name: 'Image Path (Optional) ' }); - this.browseImagesButton = this.page.getByRole('button', { name: 'button-Image Path (Optional)' }); + this.imagePathBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Image Path (Optional) ' }); + this.browseImagesButton = this.podmanMachineConfiguration.getByRole('button', { + name: 'button-Image Path (Optional)', + }); 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' }); From 4b922c44512f4c2c68f34108038e7158696b8c4b Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 6 Aug 2024 00:21:13 +0200 Subject: [PATCH 26/53] chore(tests): added connection dialog handling Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 25 ++++++++++++++++++- .../src/specs/podman-machine-rootless.spec.ts | 6 +++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 02bb2c71aaf3d..e055a7e2f11fa 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -65,6 +65,7 @@ export class CreateMachinePage extends BasePage { isRootful: boolean = true, enableUserNet: boolean = false, startNow: boolean = true, + setAsDefault: boolean = true, ): Promise { await playExpect(this.podmanMachineConfiguration).toBeVisible(); await this.podmanMachineName.fill(machineName); @@ -82,11 +83,14 @@ export class CreateMachinePage extends BasePage { } await this.createMachineButton.click(); + await this.page.waitForTimeout(60000); const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 100000 }); + await this.handleConnectionDialog(machineName, setAsDefault); + + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); @@ -115,4 +119,23 @@ export class CreateMachinePage extends BasePage { const clickableCheckbox = upperElement.getByText(checkText); await clickableCheckbox.click(); } + + async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise { + const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); + const dialogMessage = connectionDialog.getByText( + new RegExp( + "Podman Machine '" + + machineName + + "' is running but not the default machine .+ Do you want to set it as default?", + ), + ); + if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) { + let handleButtonName = 'Yes'; + if (!setAsDefault) { + handleButtonName = 'Ignore'; + } + const handleButton = connectionDialog.getByRole('button', { name: handleButtonName }); + await handleButton.click(); + } + } } diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 522b592fbc8dc..c9cde379e53b7 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -40,6 +40,7 @@ beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); page = await pdRunner.start(); pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); + process.env.KEEP_TRACES_ON_PASS = 'true'; const welcomePage = new WelcomePage(page); await welcomePage.handleWelcomePage(true); @@ -47,7 +48,7 @@ beforeAll(async () => { }); afterAll(async () => { - await deletePodmanMachine(page, PODMAN_MACHINE_NAME); + await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); await pdRunner.close(); }); @@ -66,7 +67,8 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); + await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); From 8024346028220cb4a5f315b92e5b72c630f9cef6 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 27/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index e055a7e2f11fa..69569aadd347a 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. From 020d624ca93f88dcce18f563e8e108894e261e55 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 28/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 69569aadd347a..e055a7e2f11fa 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. From 4c3d5b640afc2dfa2a48c9f456c869196242b891 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Thu, 8 Aug 2024 09:50:11 +0200 Subject: [PATCH 29/53] chore(tests): solving conflicts Signed-off-by: Tamara Babalova --- .../src/model/pages/create-machine-page.ts | 4 +--- .../src/specs/podman-machine-rootless.spec.ts | 14 +++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index e055a7e2f11fa..6e91247b7ed69 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -124,9 +124,7 @@ export class CreateMachinePage extends BasePage { const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); const dialogMessage = connectionDialog.getByText( new RegExp( - "Podman Machine '" + - machineName + - "' is running but not the default machine .+ Do you want to set it as default?", + `Podman Machine '${machineName}' is running but not the default machine .+ Do you want to set it as default?`, ), ); if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) { diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index c9cde379e53b7..ff5b6c9d70c57 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -22,8 +22,7 @@ import { expect as playExpect } from '@playwright/test'; import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; import { CreateMachinePage } from '../model/pages/create-machine-page'; -import { ResourcesPage } from '../model/pages/resources-page'; -import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page'; +import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; import { WelcomePage } from '../model/pages/welcome-page'; import { NavigationBar } from '../model/workbench/navigation'; import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; @@ -59,19 +58,16 @@ beforeEach(async ctx => { describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { test('Create a rootless machine', async () => { await navBar.openSettings(); - const resourcesPage = new ResourcesPage(page); + const podmanResources = new ResourceConnectionCardPage(page, 'podman'); - const createMachineButton = resourcesPage.podmanResources.getByRole('button', { - name: 'Create new Podman machine', - }); - await createMachineButton.click(); + await podmanResources.createButton.click(); const createMachinePage = new CreateMachinePage(page); await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); - const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); - const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); + const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); + const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); }, 150000); }); From 8f559812317ac21d90272364ace52b6c4e693643 Mon Sep 17 00:00:00 2001 From: xbabalov Date: Mon, 19 Aug 2024 22:24:22 +0200 Subject: [PATCH 30/53] chore(tests): number refactoring Signed-off-by: xbabalov --- tests/playwright/src/model/pages/create-machine-page.ts | 4 ++-- tests/playwright/src/specs/podman-machine-rootless.spec.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 6e91247b7ed69..2270bd19b379d 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -83,14 +83,14 @@ export class CreateMachinePage extends BasePage { } await this.createMachineButton.click(); - await this.page.waitForTimeout(60000); + await this.page.waitForTimeout(60_000); const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); await this.handleConnectionDialog(machineName, setAsDefault); - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10000 }); + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10_000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index ff5b6c9d70c57..f1c1b853f26b4 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -69,5 +69,5 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); - }, 150000); + }, 150_000); }); From 934862c0f002a81da8ad36ec73c5969546344bcc Mon Sep 17 00:00:00 2001 From: xbabalov Date: Tue, 24 Sep 2024 01:00:04 +0200 Subject: [PATCH 31/53] chore(tests): machine create form refactoring Signed-off-by: xbabalov --- .../src/model/pages/create-machine-page.ts | 72 ++--------------- .../pages/forms/machine-creation-form.ts | 79 +++++++++++++++++++ tests/playwright/src/utility/operations.ts | 17 ++++ 3 files changed, 102 insertions(+), 66 deletions(-) create mode 100644 tests/playwright/src/model/pages/forms/machine-creation-form.ts diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 2270bd19b379d..3ef41766cd546 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -20,67 +20,30 @@ import type { Locator, Page } from '@playwright/test'; import { expect as playExpect } from '@playwright/test'; import { BasePage } from './base-page'; +import { MachineCreationForm } from './forms/machine-creation-form'; import { ResourcesPage } from './resources-page'; export class CreateMachinePage extends BasePage { readonly heading: Locator; - readonly podmanMachineName: Locator; - readonly podmanMachineConfiguration: Locator; - readonly imagePathBox: Locator; - readonly browseImagesButton: Locator; - readonly podmanMachineCPUs: Locator; - readonly podmanMachineMemory: Locator; - readonly podmanMachineDiskSize: Locator; - readonly rootPriviledgesCheckbox: Locator; - readonly userModeNetworkingCheckbox: Locator; - readonly startNowCheckbox: Locator; readonly closeButton: Locator; readonly createMachineButton: Locator; constructor(page: Page) { super(page); this.heading = this.page.getByRole('heading', { name: 'Create Podman Machine' }); - this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); - this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); - this.imagePathBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Image Path (Optional) ' }); - this.browseImagesButton = this.podmanMachineConfiguration.getByRole('button', { - name: 'button-Image Path (Optional)', - }); - 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.rootPriviledgesCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { - name: 'Machine with root privileges', - }); - this.userModeNetworkingCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { - name: 'User mode networking', - }); - this.startNowCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { name: 'Start the machine now' }); this.closeButton = this.page.getByRole('button', { name: 'Close' }); this.createMachineButton = this.page.getByRole('button', { name: 'Create' }); } async createMachine( machineName: string, - isRootful: boolean = true, - enableUserNet: boolean = false, - startNow: boolean = true, + isRootful?: boolean, + enableUserNet?: boolean, + startNow?: boolean, setAsDefault: boolean = true, ): Promise { - await playExpect(this.podmanMachineConfiguration).toBeVisible(); - await this.podmanMachineName.fill(machineName); - - if (isRootful !== (await this.isEnabled(this.rootPriviledgesCheckbox))) { - await this.switchCheckbox(this.rootPriviledgesCheckbox); - } - - if (enableUserNet !== (await this.isEnabled(this.userModeNetworkingCheckbox))) { - await this.switchCheckbox(this.userModeNetworkingCheckbox); - } - - if (startNow !== (await this.isEnabled(this.startNowCheckbox))) { - await this.switchCheckbox(this.startNowCheckbox); - } + const machineCreationForm = new MachineCreationForm(this.page); + await machineCreationForm.configureMachine(machineName, isRootful, enableUserNet, startNow); await this.createMachineButton.click(); await this.page.waitForTimeout(60_000); @@ -97,29 +60,6 @@ export class CreateMachinePage extends BasePage { return new ResourcesPage(this.page); } - async isEnabled(checkbox: Locator): Promise { - await playExpect(checkbox).toBeVisible(); - const upperElement = checkbox.locator('..').locator('..'); - const clickableCheckbox = upperElement.getByText('Enabled'); - return await clickableCheckbox.isVisible(); - } - - async switchCheckbox(checkbox: Locator): Promise { - await playExpect(checkbox).toBeVisible(); - const upperElement = checkbox.locator('..').locator('..'); - - const wasEnabled = await this.isEnabled(checkbox); - let checkText; - if (wasEnabled) { - checkText = 'Enabled'; - } else { - checkText = 'Disabled'; - } - - const clickableCheckbox = upperElement.getByText(checkText); - await clickableCheckbox.click(); - } - async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise { const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); const dialogMessage = connectionDialog.getByText( diff --git a/tests/playwright/src/model/pages/forms/machine-creation-form.ts b/tests/playwright/src/model/pages/forms/machine-creation-form.ts new file mode 100644 index 0000000000000..799144fe19892 --- /dev/null +++ b/tests/playwright/src/model/pages/forms/machine-creation-form.ts @@ -0,0 +1,79 @@ +/********************************************************************** + * 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 { expect as playExpect, Locator, Page } from '@playwright/test'; + +import { BasePage } from '../base-page'; + +export class MachineCreationForm extends BasePage { + readonly podmanMachineConfiguration: Locator; + readonly podmanMachineName: Locator; + readonly imagePathBox: Locator; + readonly browseImagesButton: Locator; + readonly podmanMachineCPUs: Locator; + readonly podmanMachineMemory: Locator; + readonly podmanMachineDiskSize: Locator; + readonly rootPriviledgesCheckbox: Locator; + readonly userModeNetworkingCheckbox: Locator; + readonly startNowCheckbox: Locator; + + constructor(page: Page) { + super(page); + this.podmanMachineConfiguration = this.page.getByRole('form', { name: 'Properties Information' }); + this.podmanMachineName = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Name' }); + this.imagePathBox = this.podmanMachineConfiguration.getByRole('textbox', { name: 'Image Path (Optional) ' }); + this.browseImagesButton = this.podmanMachineConfiguration.getByRole('button', { + name: 'button-Image Path (Optional)', + }); + 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.rootPriviledgesCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'Machine with root privileges', + }); + this.userModeNetworkingCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { + name: 'User mode networking', + }); + this.startNowCheckbox = this.podmanMachineConfiguration.getByRole('checkbox', { name: 'Start the machine now' }); + } + + async configureMachine( + machineName: string, + isRootful: boolean = true, + enableUserNet: boolean = false, + startNow: boolean = true, + ): Promise { + await playExpect(this.podmanMachineConfiguration).toBeVisible(); + await this.podmanMachineName.fill(machineName); + + if (isRootful !== (await this.rootPriviledgesCheckbox.isChecked())) { + await this.rootPriviledgesCheckbox.locator('..').click(); + playExpect(await this.rootPriviledgesCheckbox.isChecked()).toBe(isRootful); + } + + if (enableUserNet !== (await this.userModeNetworkingCheckbox.isChecked())) { + await this.userModeNetworkingCheckbox.locator('..').click(); + playExpect(await this.userModeNetworkingCheckbox.isChecked()).toBe(enableUserNet); + } + + if (startNow !== (await this.startNowCheckbox.isChecked())) { + await this.startNowCheckbox.locator('..').click(); + playExpect(await this.startNowCheckbox.isChecked()).toBe(startNow); + } + } +} diff --git a/tests/playwright/src/utility/operations.ts b/tests/playwright/src/utility/operations.ts index 9d2fe0dd89f98..fb9b3ede70bd2 100644 --- a/tests/playwright/src/utility/operations.ts +++ b/tests/playwright/src/utility/operations.ts @@ -234,12 +234,29 @@ export async function deletePodmanMachine(page: Page, machineVisibleName: string } await podmanResourceCard.performConnectionAction(ResourceElementActions.Delete); await playExpect(podmanResourceCard.resourceElement).toBeHidden({ timeout: 60_000 }); + + const defaultMachineCard = new ResourceConnectionCardPage(page, RESOURCE_NAME, 'podman-machine-default'); + if (await defaultMachineCard.resourceElement.isVisible()) { + await handleResetDefaultConnectionDialog(page); + } } else { console.log(`Podman machine [${machineVisibleName}] not present, skipping deletion.`); } }); } +export async function handleResetDefaultConnectionDialog(page: Page): Promise { + const connectionDialog = page.getByRole('dialog', { name: 'Podman' }); + await playExpect(connectionDialog).toBeVisible({ timeout: 20_000 }); + + const handleButton = connectionDialog.getByRole('button', { name: 'Yes' }); + await handleButton.click(); + + await playExpect(connectionDialog).toBeVisible(); + const okButton = connectionDialog.getByRole('button', { name: 'OK' }); + await okButton.click(); +} + export async function getVolumeNameForContainer(page: Page, containerName: string): Promise { return await test.step('Get volume name for container', async () => { let volumeName; From ad473a2227b2f5a4cde4e3cfa2b8b766c6001760 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Fri, 26 Apr 2024 02:15:15 +0200 Subject: [PATCH 32/53] chore(tests): rootless machine creation test added Signed-off-by: Tamara Babalova --- .../src/specs/podman-machine-rootless.spec.ts | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index f1c1b853f26b4..692626c067f64 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -22,7 +22,8 @@ import { expect as playExpect } from '@playwright/test'; import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; import { CreateMachinePage } from '../model/pages/create-machine-page'; -import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; +import { ResourcesPage } from '../model/pages/resources-page'; +import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page'; import { WelcomePage } from '../model/pages/welcome-page'; import { NavigationBar } from '../model/workbench/navigation'; import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; @@ -32,14 +33,12 @@ import { deletePodmanMachine } from '../utility/operations'; let pdRunner: PodmanDesktopRunner; let page: Page; let navBar: NavigationBar; -const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; -const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; +const PODMAN_MACHINE_NAME: string = 'Podman Machine Rootless'; beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); page = await pdRunner.start(); pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); - process.env.KEEP_TRACES_ON_PASS = 'true'; const welcomePage = new WelcomePage(page); await welcomePage.handleWelcomePage(true); @@ -47,7 +46,7 @@ beforeAll(async () => { }); afterAll(async () => { - await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); + await deletePodmanMachine(page, PODMAN_MACHINE_NAME); await pdRunner.close(); }); @@ -58,16 +57,18 @@ beforeEach(async ctx => { describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { test('Create a rootless machine', async () => { await navBar.openSettings(); - const podmanResources = new ResourceConnectionCardPage(page, 'podman'); + const resourcesPage = new ResourcesPage(page); - await podmanResources.createButton.click(); + const createMachineButton = resourcesPage.podmanResources.getByRole('button', { + name: 'Create new Podman machine', + }); + await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); - await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); - const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); - const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); - playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); - }, 150_000); + const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); + const connectionStatus = await machineBox.machineConnectionStatus.allTextContents(); + playExpect(connectionStatus[0] === 'RUNNING').toBeTruthy(); + }); }); From 36bbb3293587d8cafa5d1e602550d6b9e378b6d9 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 33/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- .../playwright/src/specs/podman-machine-rootless.spec.ts | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 3ef41766cd546..98c87ede3f8dd 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 692626c067f64..22b59ea99d581 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -68,7 +68,9 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); - const connectionStatus = await machineBox.machineConnectionStatus.allTextContents(); - playExpect(connectionStatus[0] === 'RUNNING').toBeTruthy(); - }); + const connectionStatusLabel = await machineBox.machineConnectionStatus + .getByLabel('Connection Status Label') + .textContent(); + playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); + }, 150000); }); From 13e9bdf35990146ce1e9800bd5dfae75163db8cb Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 34/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- .../playwright/src/model/pages/create-machine-page.ts | 2 +- .../src/specs/podman-machine-rootless.spec.ts | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 98c87ede3f8dd..3ef41766cd546 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 22b59ea99d581..522b592fbc8dc 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -33,7 +33,8 @@ import { deletePodmanMachine } from '../utility/operations'; let pdRunner: PodmanDesktopRunner; let page: Page; let navBar: NavigationBar; -const PODMAN_MACHINE_NAME: string = 'Podman Machine Rootless'; +const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; +const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); @@ -65,12 +66,10 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true); - const machineBox = new ResourcesPodmanConnections(page, PODMAN_MACHINE_NAME); - const connectionStatusLabel = await machineBox.machineConnectionStatus - .getByLabel('Connection Status Label') - .textContent(); + const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); + const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); }, 150000); }); From 28fb65304606d53aab50fe22f164ab7b6d639325 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 6 Aug 2024 00:21:13 +0200 Subject: [PATCH 35/53] chore(tests): added connection dialog handling Signed-off-by: Tamara Babalova --- tests/playwright/src/specs/podman-machine-rootless.spec.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 522b592fbc8dc..c9cde379e53b7 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -40,6 +40,7 @@ beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); page = await pdRunner.start(); pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); + process.env.KEEP_TRACES_ON_PASS = 'true'; const welcomePage = new WelcomePage(page); await welcomePage.handleWelcomePage(true); @@ -47,7 +48,7 @@ beforeAll(async () => { }); afterAll(async () => { - await deletePodmanMachine(page, PODMAN_MACHINE_NAME); + await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); await pdRunner.close(); }); @@ -66,7 +67,8 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification await createMachineButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); + await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); From d823daee947a8935f5fe139cd5d88eaa65df3bf9 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 36/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 3ef41766cd546..98c87ede3f8dd 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. From 2065a2fac9df833d024bef22c7e97b1e25d18505 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 37/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 98c87ede3f8dd..3ef41766cd546 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. From 65bbb5a6cfcba770454827c124ddbdb30330b6da Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Thu, 8 Aug 2024 09:50:11 +0200 Subject: [PATCH 38/53] chore(tests): solving conflicts Signed-off-by: Tamara Babalova --- .../src/specs/podman-machine-rootless.spec.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index c9cde379e53b7..ff5b6c9d70c57 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -22,8 +22,7 @@ import { expect as playExpect } from '@playwright/test'; import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; import { CreateMachinePage } from '../model/pages/create-machine-page'; -import { ResourcesPage } from '../model/pages/resources-page'; -import { ResourcesPodmanConnections } from '../model/pages/resources-podman-connections-page'; +import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; import { WelcomePage } from '../model/pages/welcome-page'; import { NavigationBar } from '../model/workbench/navigation'; import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; @@ -59,19 +58,16 @@ beforeEach(async ctx => { describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { test('Create a rootless machine', async () => { await navBar.openSettings(); - const resourcesPage = new ResourcesPage(page); + const podmanResources = new ResourceConnectionCardPage(page, 'podman'); - const createMachineButton = resourcesPage.podmanResources.getByRole('button', { - name: 'Create new Podman machine', - }); - await createMachineButton.click(); + await podmanResources.createButton.click(); const createMachinePage = new CreateMachinePage(page); await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); - const machineBox = new ResourcesPodmanConnections(page, MACHINE_VISIBLE_NAME); - const connectionStatusLabel = await machineBox.machineConnectionStatus.textContent(); + const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); + const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); }, 150000); }); From 3710f9f49372aecb6195d114c7352ca24cc5e66e Mon Sep 17 00:00:00 2001 From: xbabalov Date: Mon, 19 Aug 2024 22:24:22 +0200 Subject: [PATCH 39/53] chore(tests): number refactoring Signed-off-by: xbabalov --- tests/playwright/src/specs/podman-machine-rootless.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index ff5b6c9d70c57..f1c1b853f26b4 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -69,5 +69,5 @@ describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); - }, 150000); + }, 150_000); }); From 18745d93b002daf28bc45a5e6a3a790969193a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tamara=20Bab=C3=A1lov=C3=A1?= Date: Thu, 5 Sep 2024 02:54:09 -0700 Subject: [PATCH 40/53] =?UTF-8?q?chore(tests):=20fixing=20test=20runtime?= =?UTF-8?q?=20Signed-off-by:=20Tamara=20Bab=C3=A1lov=C3=A1=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/playwright/src/index.ts | 1 + .../src/model/pages/create-machine-page.ts | 3 ++ .../src/specs/podman-machine-rootless.spec.ts | 31 ++++++++++--------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/tests/playwright/src/index.ts b/tests/playwright/src/index.ts index 334b5ce890d92..fdc4ddbb33425 100644 --- a/tests/playwright/src/index.ts +++ b/tests/playwright/src/index.ts @@ -44,6 +44,7 @@ export * from './model/pages/compose-onboarding/compose-wide-install-page'; export * from './model/pages/container-details-page'; export * from './model/pages/containers-page'; export * from './model/pages/create-kind-cluster-page'; +export * from './model/pages/create-machine-page'; export * from './model/pages/create-pod-page'; export * from './model/pages/dashboard-page'; export * from './model/pages/deploy-to-kubernetes-page'; diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 3ef41766cd546..70b9d0d4ce96d 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -19,6 +19,8 @@ import type { Locator, Page } from '@playwright/test'; import { expect as playExpect } from '@playwright/test'; +import { delay } from '/@/utility/wait'; + import { BasePage } from './base-page'; import { MachineCreationForm } from './forms/machine-creation-form'; import { ResourcesPage } from './resources-page'; @@ -51,6 +53,7 @@ export class CreateMachinePage extends BasePage { const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); + await delay(5000); await this.handleConnectionDialog(machineName, setAsDefault); await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10_000 }); diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index f1c1b853f26b4..4bf7215c79c5e 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -18,16 +18,16 @@ import * as os from 'node:os'; import type { Page } from '@playwright/test'; -import { expect as playExpect } from '@playwright/test'; -import { afterAll, beforeAll, beforeEach, describe, test } from 'vitest'; +import { expect as playExpect, test } from '@playwright/test'; +import { ResourceElementState } from '../model/core/states'; import { CreateMachinePage } from '../model/pages/create-machine-page'; import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; import { WelcomePage } from '../model/pages/welcome-page'; import { NavigationBar } from '../model/workbench/navigation'; import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; -import type { RunnerTestContext } from '../testContext/runner-test-context'; import { deletePodmanMachine } from '../utility/operations'; +import { delay } from '../utility/wait'; let pdRunner: PodmanDesktopRunner; let page: Page; @@ -35,7 +35,7 @@ let navBar: NavigationBar; const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; -beforeAll(async () => { +test.beforeAll(async () => { pdRunner = new PodmanDesktopRunner(); page = await pdRunner.start(); pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); @@ -46,28 +46,31 @@ beforeAll(async () => { navBar = new NavigationBar(page); }); -afterAll(async () => { - await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); +test.afterAll(async () => { await pdRunner.close(); }); -beforeEach(async ctx => { - ctx.pdRunner = pdRunner; -}); +test.describe('Rootless Podman machine Verification', () => { + test.skip(os.platform() === 'linux', 'runs only on windows and mac'); -describe.skipIf(os.platform() === 'linux')('Rootless Podman machine Verification', async () => { test('Create a rootless machine', async () => { + test.setTimeout(200000); + await navBar.openSettings(); const podmanResources = new ResourceConnectionCardPage(page, 'podman'); await podmanResources.createButton.click(); const createMachinePage = new CreateMachinePage(page); - await createMachinePage.createMachine(PODMAN_MACHINE_NAME, false, false, true, false); + await createMachinePage.createMachine(PODMAN_MACHINE_NAME, { isRootful: false, setAsDefault: false }); + await delay(5000); await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); - const connectionStatusLabel = await machineBox.resourceElementConnectionStatus.textContent(); - playExpect(connectionStatusLabel === 'RUNNING').toBeTruthy(); - }, 150_000); + await playExpect(machineBox.resourceElementConnectionStatus).toHaveText(ResourceElementState.Running); + }); + test('Cleanup', async () => { + test.setTimeout(150000); + await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); + }); }); From f914a7ff9f5751cde7a93ae5db24ee7774e306a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tamara=20Bab=C3=A1lov=C3=A1?= Date: Thu, 5 Sep 2024 03:04:00 -0700 Subject: [PATCH 41/53] =?UTF-8?q?chore(tests):=20refactoring=20for=20fixtu?= =?UTF-8?q?res=20Signed-off-by:=20Tamara=20Bab=C3=A1lov=C3=A1=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/model/pages/create-machine-page.ts | 28 ++++++------- .../src/specs/podman-machine-rootless.spec.ts | 40 +++++-------------- tests/playwright/src/utility/operations.ts | 2 +- 3 files changed, 24 insertions(+), 46 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 70b9d0d4ce96d..b29e7904c72b7 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -19,8 +19,6 @@ import type { Locator, Page } from '@playwright/test'; import { expect as playExpect } from '@playwright/test'; -import { delay } from '/@/utility/wait'; - import { BasePage } from './base-page'; import { MachineCreationForm } from './forms/machine-creation-form'; import { ResourcesPage } from './resources-page'; @@ -47,15 +45,14 @@ export class CreateMachinePage extends BasePage { const machineCreationForm = new MachineCreationForm(this.page); await machineCreationForm.configureMachine(machineName, isRootful, enableUserNet, startNow); + await playExpect(this.createMachineButton).toBeEnabled(); await this.createMachineButton.click(); - await this.page.waitForTimeout(60_000); - - const successfulCreationMessage = this.page.getByText('Successful operation'); - const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await delay(5000); + // wait for machine creation and handle connections await this.handleConnectionDialog(machineName, setAsDefault); + const successfulCreationMessage = this.page.getByText('Successful operation'); + const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10_000 }); await playExpect(goBackToResourcesButton).toBeVisible(); await goBackToResourcesButton.click(); @@ -65,18 +62,17 @@ export class CreateMachinePage extends BasePage { async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise { const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); - const dialogMessage = connectionDialog.getByText( + await playExpect(connectionDialog).toBeVisible({ timeout: 60_000 }); + + const dialogMessage = connectionDialog.getByLabel('Dialog Message'); + await playExpect(dialogMessage).toHaveText( new RegExp( `Podman Machine '${machineName}' is running but not the default machine .+ Do you want to set it as default?`, ), ); - if ((await connectionDialog.isVisible()) && (await dialogMessage.isVisible())) { - let handleButtonName = 'Yes'; - if (!setAsDefault) { - handleButtonName = 'Ignore'; - } - const handleButton = connectionDialog.getByRole('button', { name: handleButtonName }); - await handleButton.click(); - } + + const handleButtonName = setAsDefault ? 'Yes' : 'Ignore'; + const handleButton = connectionDialog.getByRole('button', { name: handleButtonName }); + await handleButton.click(); } } diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 4bf7215c79c5e..85a853b73598c 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -17,60 +17,42 @@ ***********************************************************************/ import * as os from 'node:os'; -import type { Page } from '@playwright/test'; -import { expect as playExpect, test } from '@playwright/test'; - import { ResourceElementState } from '../model/core/states'; import { CreateMachinePage } from '../model/pages/create-machine-page'; import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; -import { WelcomePage } from '../model/pages/welcome-page'; -import { NavigationBar } from '../model/workbench/navigation'; -import { PodmanDesktopRunner } from '../runner/podman-desktop-runner'; +import { expect as playExpect, test } from '../utility/fixtures'; import { deletePodmanMachine } from '../utility/operations'; -import { delay } from '../utility/wait'; -let pdRunner: PodmanDesktopRunner; -let page: Page; -let navBar: NavigationBar; const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; -const MACHINE_VISIBLE_NAME: string = 'Podman Machine rootless'; -test.beforeAll(async () => { - pdRunner = new PodmanDesktopRunner(); - page = await pdRunner.start(); +test.beforeAll(async ({ pdRunner, welcomePage }) => { pdRunner.setVideoAndTraceName('podman-rootless-machine-e2e'); process.env.KEEP_TRACES_ON_PASS = 'true'; - const welcomePage = new WelcomePage(page); await welcomePage.handleWelcomePage(true); - navBar = new NavigationBar(page); }); -test.afterAll(async () => { +test.afterAll(async ({ pdRunner }) => { await pdRunner.close(); }); +test.skip(os.platform() === 'linux', 'Runs only on Windows and Mac'); test.describe('Rootless Podman machine Verification', () => { - test.skip(os.platform() === 'linux', 'runs only on windows and mac'); - - test('Create a rootless machine', async () => { - test.setTimeout(200000); + test('Create a rootless machine', async ({ page, navigationBar }) => { + test.setTimeout(200_000); - await navBar.openSettings(); + await navigationBar.openSettings(); const podmanResources = new ResourceConnectionCardPage(page, 'podman'); - await podmanResources.createButton.click(); const createMachinePage = new CreateMachinePage(page); await createMachinePage.createMachine(PODMAN_MACHINE_NAME, { isRootful: false, setAsDefault: false }); - await delay(5000); - await createMachinePage.handleConnectionDialog(PODMAN_MACHINE_NAME, false); - const machineBox = new ResourceConnectionCardPage(page, 'podman', MACHINE_VISIBLE_NAME); + const machineBox = new ResourceConnectionCardPage(page, 'podman', PODMAN_MACHINE_NAME); //does not work with visible name await playExpect(machineBox.resourceElementConnectionStatus).toHaveText(ResourceElementState.Running); }); - test('Cleanup', async () => { - test.setTimeout(150000); - await deletePodmanMachine(page, MACHINE_VISIBLE_NAME); + test('Clean up rootless machine', async ({ page }) => { + test.setTimeout(150_000); + await deletePodmanMachine(page, PODMAN_MACHINE_NAME); }); }); diff --git a/tests/playwright/src/utility/operations.ts b/tests/playwright/src/utility/operations.ts index fb9b3ede70bd2..2f86f94078a4c 100644 --- a/tests/playwright/src/utility/operations.ts +++ b/tests/playwright/src/utility/operations.ts @@ -316,7 +316,7 @@ export async function createKindCluster( page: Page, clusterName: string, usedefaultOptions: boolean, - timeout: number = 200000, + timeout: number = 200_000, { providerType, httpPort, httpsPort, useIngressController, containerImage }: KindClusterOptions = {}, ): Promise { await test.step('Create Kind cluster', async () => { From 1db42fdb1716ec94172aa74cbfb1d21c35c02530 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 42/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index b29e7904c72b7..a434edabb5439 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. From 6292ffc4f11bfa8cdcb549d4fbb1fd381e8bc48a Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 43/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index a434edabb5439..b29e7904c72b7 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. From 10cbcc5abc04573372648b57b9295ba818410820 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 44/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index b29e7904c72b7..a434edabb5439 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. From 3b627aa35f49ad17c004b3b70c518edae77c1fe3 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 45/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index a434edabb5439..b29e7904c72b7 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. From b77d7c98a319b675f13078ec6d25856ab8eb5173 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 46/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index b29e7904c72b7..a434edabb5439 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. From e2ad37a6d364fd09de7d9a70e0a4867629f39e89 Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 47/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index a434edabb5439..b29e7904c72b7 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. From 3c163f6c4d5e2f8c9dbc975cebd8fbcf1190adac Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 4 Jun 2024 01:51:05 +0200 Subject: [PATCH 48/53] chore(tests): creating rootless machine e2e test fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index b29e7904c72b7..a434edabb5439 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2023 Red Hat, Inc. + * 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. From b0f3135ab2c7e37717ad5e77cae7e8a42fb288df Mon Sep 17 00:00:00 2001 From: Tamara Babalova Date: Tue, 2 Jul 2024 09:57:15 +0200 Subject: [PATCH 49/53] chore(tests): create rootless fixed Signed-off-by: Tamara Babalova --- tests/playwright/src/model/pages/create-machine-page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index a434edabb5439..b29e7904c72b7 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -1,5 +1,5 @@ /********************************************************************** - * Copyright (C) 2024 Red Hat, Inc. + * Copyright (C) 2023 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. From 66844345d1c5d9ef2ef3d76ce688ba3902e80130 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tamara=20Bab=C3=A1lov=C3=A1?= Date: Thu, 5 Sep 2024 02:54:09 -0700 Subject: [PATCH 50/53] =?UTF-8?q?chore(tests):=20fixing=20test=20runtime?= =?UTF-8?q?=20Signed-off-by:=20Tamara=20Bab=C3=A1lov=C3=A1=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/playwright/src/model/pages/create-machine-page.ts | 2 ++ tests/playwright/src/specs/podman-machine-rootless.spec.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index b29e7904c72b7..2104738b920ef 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -19,6 +19,8 @@ import type { Locator, Page } from '@playwright/test'; import { expect as playExpect } from '@playwright/test'; +import { delay } from '/@/utility/wait'; + import { BasePage } from './base-page'; import { MachineCreationForm } from './forms/machine-creation-form'; import { ResourcesPage } from './resources-page'; diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 85a853b73598c..149e6b560d6e1 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -22,6 +22,7 @@ import { CreateMachinePage } from '../model/pages/create-machine-page'; import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; import { expect as playExpect, test } from '../utility/fixtures'; import { deletePodmanMachine } from '../utility/operations'; +import { delay } from '../utility/wait'; const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; From 4143c2f1bb145a1fdd774270f4e1f6a8d3acd114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tamara=20Bab=C3=A1lov=C3=A1?= Date: Thu, 5 Sep 2024 03:04:00 -0700 Subject: [PATCH 51/53] =?UTF-8?q?chore(tests):=20refactoring=20for=20fixtu?= =?UTF-8?q?res=20Signed-off-by:=20Tamara=20Bab=C3=A1lov=C3=A1=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/playwright/src/model/pages/create-machine-page.ts | 2 -- tests/playwright/src/specs/podman-machine-rootless.spec.ts | 1 - 2 files changed, 3 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 2104738b920ef..b29e7904c72b7 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -19,8 +19,6 @@ import type { Locator, Page } from '@playwright/test'; import { expect as playExpect } from '@playwright/test'; -import { delay } from '/@/utility/wait'; - import { BasePage } from './base-page'; import { MachineCreationForm } from './forms/machine-creation-form'; import { ResourcesPage } from './resources-page'; diff --git a/tests/playwright/src/specs/podman-machine-rootless.spec.ts b/tests/playwright/src/specs/podman-machine-rootless.spec.ts index 149e6b560d6e1..85a853b73598c 100644 --- a/tests/playwright/src/specs/podman-machine-rootless.spec.ts +++ b/tests/playwright/src/specs/podman-machine-rootless.spec.ts @@ -22,7 +22,6 @@ import { CreateMachinePage } from '../model/pages/create-machine-page'; import { ResourceConnectionCardPage } from '../model/pages/resource-connection-card-page'; import { expect as playExpect, test } from '../utility/fixtures'; import { deletePodmanMachine } from '../utility/operations'; -import { delay } from '../utility/wait'; const PODMAN_MACHINE_NAME: string = 'podman-machine-rootless'; From c0fbeece9d102543b75f5cd1d865009edfe18284 Mon Sep 17 00:00:00 2001 From: xbabalov Date: Tue, 24 Sep 2024 09:28:39 +0200 Subject: [PATCH 52/53] chore(tests): generalize connection handling dialog Signed-off-by: xbabalov --- .../src/model/pages/create-machine-page.ts | 14 +++++++++----- .../src/specs/podman-machine-tests.spec.ts | 2 +- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/playwright/src/model/pages/create-machine-page.ts b/tests/playwright/src/model/pages/create-machine-page.ts index 3390d62167454..ef882ce5ee4a2 100644 --- a/tests/playwright/src/model/pages/create-machine-page.ts +++ b/tests/playwright/src/model/pages/create-machine-page.ts @@ -44,18 +44,22 @@ export class CreateMachinePage extends BasePage { const successfulCreationMessage = this.page.getByText('Successful operation'); const goBackToResourcesButton = this.page.getByRole('button', { name: 'Go back to resources' }); - await this.handleConnectionDialog(machineName, setAsDefault); - - await playExpect(successfulCreationMessage).toBeVisible({ timeout: 10_000 }); + await playExpect(successfulCreationMessage).toBeVisible({ timeout: 60_000 }); await playExpect(goBackToResourcesButton).toBeVisible(); - await goBackToResourcesButton.click(); + try { + await this.handleConnectionDialog(machineName, setAsDefault); + } catch (error) { + console.log('No handling dialog displayed', error); + } + + await goBackToResourcesButton.click(); return new ResourcesPage(this.page); } async handleConnectionDialog(machineName: string, setAsDefault: boolean): Promise { const connectionDialog = this.page.getByRole('dialog', { name: 'Podman' }); - await playExpect(connectionDialog).toBeVisible({ timeout: 60_000 }); + await playExpect(connectionDialog).toBeVisible({ timeout: 10_000 }); const dialogMessage = connectionDialog.getByLabel('Dialog Message'); await playExpect(dialogMessage).toHaveText( diff --git a/tests/playwright/src/specs/podman-machine-tests.spec.ts b/tests/playwright/src/specs/podman-machine-tests.spec.ts index 2861111fc9227..720b19ce024fb 100644 --- a/tests/playwright/src/specs/podman-machine-tests.spec.ts +++ b/tests/playwright/src/specs/podman-machine-tests.spec.ts @@ -202,7 +202,7 @@ test.describe.serial(`Podman machine switching validation `, () => { await handleConfirmationDialog(page, 'Podman', true, 'Yes'); await handleConfirmationDialog(page, 'Podman', true, 'OK'); } catch (error) { - console.log('No handing dialog displayed', error); + console.log('No handling dialog displayed', error); } }); }); From 5a046a10b1e3f7be58d1abe44167f01bc68ea090 Mon Sep 17 00:00:00 2001 From: tbabalov <57829934+xbabalov@users.noreply.github.com> Date: Wed, 25 Sep 2024 01:12:50 +0200 Subject: [PATCH 53/53] Update podman-machine-tests.spec.ts Signed-off-by: tbabalov <57829934+xbabalov@users.noreply.github.com> --- tests/playwright/src/specs/podman-machine-tests.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/playwright/src/specs/podman-machine-tests.spec.ts b/tests/playwright/src/specs/podman-machine-tests.spec.ts index 07932162503c0..ccf007c96d81b 100644 --- a/tests/playwright/src/specs/podman-machine-tests.spec.ts +++ b/tests/playwright/src/specs/podman-machine-tests.spec.ts @@ -22,7 +22,7 @@ import { ResourceConnectionCardPage } from '../model/pages/resource-connection-c import { ResourcesPage } from '../model/pages/resources-page'; import { expect as playExpect, test } from '../utility/fixtures'; import { deletePodmanMachine, handleConfirmationDialog } from '../utility/operations'; -import { isLinux, isWindows } from '../utility/platform'; +import { isLinux } from '../utility/platform'; import { waitForPodmanMachineStartup } from '../utility/wait'; const DEFAULT_PODMAN_MACHINE = 'Podman Machine';