Skip to content

Commit

Permalink
chore(tests): add podman desktop update e2e test (#8653)
Browse files Browse the repository at this point in the history
* chore(test): add podman desktop update e2e test with workflows

Signed-off-by: Ondrej Dockal <[email protected]>
  • Loading branch information
odockal authored Sep 9, 2024
1 parent c5ac7fa commit 4e583e9
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 8 deletions.
70 changes: 68 additions & 2 deletions .github/workflows/e2e-main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ on:

jobs:
e2e-tests:
name: Run E2E tests
name: Run All E2E tests
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -85,7 +85,7 @@ jobs:
- name: Execute pnpm
run: pnpm install

- name: Run All E2E tests
- name: Run E2E tests
env:
PODMANDESKTOP_CI_BOT_TOKEN: ${{ secrets.PODMANDESKTOP_CI_BOT_TOKEN }}
TEST_PODMAN_MACHINE: 'true'
Expand All @@ -100,3 +100,69 @@ jobs:
./tests/output/
./tests/**/output/junit*.xml
!./tests/**/traces/raw
win-update-e2e-test:
name: win update e2e tests
runs-on: ${{ matrix.os }}
timeout-minutes: 40
strategy:
fail-fast: false
matrix:
os: [windows-2022]
steps:
- uses: actions/checkout@v4
with:
repository: ${{ github.event.inputs.organization }}/${{ github.event.inputs.repositoryName }}
ref: ${{ github.event.inputs.branch }}
if: github.event_name == 'workflow_dispatch'

- uses: actions/checkout@v4
if: github.event_name == 'push'

- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false

- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Execute pnpm
run: pnpm install

- name: Execute PNPM
run: pnpm install --frozen-lockfile

- name: Adjust/Downgrade local podman desktop version Windows
if: ${{ matrix.os=='windows-2022'}}
run: |
$version="1.0.0"
jq --arg version "$version" '.version = $version' package.json | Out-File -FilePath package.json_tmp
Move-Item -Path package.json_tmp -Destination package.json -Force
- name: Build Podman Desktop locally with electron updater included
env:
ELECTRON_ENABLE_INSPECT: true
run: |
pnpm compile:current --win nsis
$path=('./dist/win-unpacked/Podman Desktop.exe' | resolve-path).ProviderPath
echo $path
echo ("PODMAN_DESKTOP_BINARY=" + $path) >> $env:GITHUB_ENV
- name: Run E2E Update test
env:
UPDATE_PODMAN_DESKTOP: true
run: |
echo "${{ env.PODMAN_DESKTOP_BINARY }}"
pnpm test:e2e:update:run
- uses: actions/upload-artifact@v4
if: always()
with:
name: update-e2e-test
path: |
./tests/output/
./tests/**/output/junit*.xml
!./tests/**/traces/raw
101 changes: 99 additions & 2 deletions .github/workflows/pr-check.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (C) 2022 Red Hat, Inc.
# Copyright (C) 2022-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.
Expand All @@ -17,7 +17,9 @@

name: pr-check

on: [pull_request]
on:
pull_request:
types: [labeled, synchronize, opened, reopened]

jobs:
windows:
Expand Down Expand Up @@ -324,3 +326,98 @@ jobs:
./tests/output/
./tests/**/output/junit*.xml
!./tests/**/traces/raw
detect_pnpm_changes:
name: Detect pnpm lock or pr-check files changes
runs-on: ubuntu-24.04
outputs:
pnpm_lock_changed: ${{ steps.pnpm_changed.outputs.PNPM_LOCK_CHANGED }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2

- name: Evaluate changes in files
id: pnpm_changed
run: |
git fetch origin ${{ github.event.pull_request.base.ref }}
git diff --name-only origin/${{ github.event.pull_request.base.ref }} HEAD > changes.txt
if grep -q -e 'pnpm-lock.yaml' -e 'pr-check.yaml' changes.txt; then
echo "PNPM_LOCK_CHANGED=true" >> $GITHUB_OUTPUT
else
echo "PNPM_LOCK_CHANGED=false" >> $GITHUB_OUTPUT
fi
run-update-e2e-test:
name: win update e2e tests
needs: detect_pnpm_changes
if: contains(github.event.pull_request.labels.*.name, 'area/update') || needs.detect_pnpm_changes.outputs.pnpm_lock_changed == 'true'
runs-on: windows-2022
timeout-minutes: 60
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false

- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Execute pnpm
run: pnpm install

- name: Execute PNPM
run: pnpm install --frozen-lockfile

- name: Adjust/Downgrade local podman desktop version Windows
run: |
$version="1.0.0"
jq --arg version "$version" '.version = $version' package.json | Out-File -FilePath package.json_tmp
Move-Item -Path package.json_tmp -Destination package.json -Force
- name: Build Podman Desktop locally with electron updater included
env:
ELECTRON_ENABLE_INSPECT: true
run: |
pnpm compile:current --win nsis
$path=('./dist/win-unpacked/Podman Desktop.exe' | resolve-path).ProviderPath
echo $path
echo ("PODMAN_DESKTOP_BINARY=" + $path) >> $env:GITHUB_ENV
- name: Run E2E Update test
env:
UPDATE_PODMAN_DESKTOP: true
run: |
echo "${{ env.PODMAN_DESKTOP_BINARY }}"
pnpm test:e2e:update:run
- uses: actions/upload-artifact@v4
if: always()
with:
name: win-update-e2e-test
path: |
./tests/**/output/
./tests/**/output/junit*.xml
!./tests/**/traces/raw
update-e2e-test:
name: update E2E test
runs-on: ubuntu-24.04
needs: run-update-e2e-test
if: |
always()
steps:
- name: Evaluate the Windows Update test results
run: |
echo "Windows updater result: ${{ needs.run-update-e2e-test.result }}"
if [ "${{ needs.run-update-e2e-test.result }}" = "failure" ]; then
echo "Windows udpater test failed..."
exit 1
else
echo "Windows updater test succeeded or was skipped..."
fi
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
"test:e2e:extension:run": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' -- npx playwright test tests/playwright/src/specs/extension-installation.spec.ts",
"test:e2e:pw": "npm run test:e2e:build && npm run test:e2e:pw:run",
"test:e2e:pw:run": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' -- npx playwright test tests/playwright/src/specs/pod-smoke.spec.ts",
"test:e2e:update": "npm run test:e2e:build && npm run test:e2e:update:run",
"test:e2e:update:run": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' -- npx playwright test tests/playwright/src/specs/installation/update-install.spec.ts",
"test:e2e:copy": "cp ../podman-desktop-extension-bootc/tests/src/bootc-extension.spec.ts tests/src/",
"test:main": "vitest run -r packages/main --passWithNoTests --coverage",
"test:preload": "vitest run -r packages/preload --passWithNoTests --coverage",
Expand Down
4 changes: 3 additions & 1 deletion packages/renderer/src/lib/statusbar/StatusBar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ onMount(async () => {
</script>

<div
class="flex justify-between px-1 bg-[var(--pd-statusbar-bg)] text-[var(--pd-statusbar-text)] text-sm space-x-2 z-40">
class="flex justify-between px-1 bg-[var(--pd-statusbar-bg)] text-[var(--pd-statusbar-text)] text-sm space-x-2 z-40"
role="contentinfo"
aria-label="Status Bar">
<div class="flex flex-wrap gap-x-1.5 h-full">
{#each leftEntries as entry}
<StatusBarItem entry={entry} />
Expand Down
18 changes: 16 additions & 2 deletions tests/playwright/src/model/workbench/status-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,29 @@ import { handleConfirmationDialog } from '../../utility/operations';
import { BasePage } from '../pages/base-page';

export class StatusBar extends BasePage {
readonly content: Locator;
readonly kindInstallationButton: Locator;
readonly kubernetesContext: Locator;
readonly versionButton: Locator;
readonly updateButtonTitle: Locator;
readonly shareYourFeedbackButton: Locator;
readonly troubleshootingButton: Locator;
readonly tasksButton: Locator;
readonly helpButton: Locator;

constructor(page: Page) {
super(page);
this.kindInstallationButton = this.page.getByTitle(
this.content = page.getByRole('contentinfo', { name: 'Status Bar' });
this.kindInstallationButton = this.content.getByTitle(
'Kind not found on your system, click to download and install it',
);
this.kubernetesContext = this.page.getByTitle('Current Kubernetes Context');
this.kubernetesContext = this.content.getByTitle('Current Kubernetes Context');
this.versionButton = this.content.getByRole('button', { name: /^v\d+\.\d+\.\d+(-\w+)?$/ });
this.updateButtonTitle = this.content.getByRole('button').and(this.content.getByTitle('Update available'));
this.shareYourFeedbackButton = this.content.getByRole('button').and(this.content.getByTitle('Share your feedback'));
this.troubleshootingButton = this.content.getByRole('button').and(this.content.getByTitle('Troubleshooting'));
this.tasksButton = this.content.getByRole('button').and(this.content.getByTitle('Tasks'));
this.helpButton = this.content.getByRole('button').and(this.content.getByTitle('Help'));
}

public async installKindCLI(): Promise<void> {
Expand Down
94 changes: 94 additions & 0 deletions tests/playwright/src/specs/installation/update-install.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/

import type { Locator } from '@playwright/test';

import type { StatusBar } from '../../model/workbench/status-bar';
import { expect as playExpect, test } from '../../utility/fixtures';
import { handleConfirmationDialog } from '../../utility/operations';

let sBar: StatusBar;
let updateAvailableDialog: Locator;
let updateDialog: Locator;
let updateDownloadedDialog: Locator;
const performUpdate = process.env.UPDATE_PODMAN_DESKTOP ? process.env.UPDATE_PODMAN_DESKTOP : false;

test.beforeAll(async ({ runner, page, statusBar }) => {
runner.setVideoAndTraceName('update-e2e');

sBar = statusBar;
updateAvailableDialog = page.getByRole('dialog', { name: 'Update Available now' });
updateDialog = page.getByRole('dialog', { name: 'Update', exact: true });
updateDownloadedDialog = page.getByRole('dialog', { name: 'Update Downloaded', exact: true });
});

test.afterAll(async ({ runner }) => {
await runner.close();
});

test.describe.serial('Podman Desktop Update Update installation offering', () => {
test('Update is offered automatically on startup', async ({ welcomePage }) => {
await playExpect(updateAvailableDialog).toBeVisible();
const updateNowButton = updateAvailableDialog.getByRole('button', { name: 'Update Now' });
await playExpect(updateNowButton).toBeVisible();
const doNotshowButton = updateAvailableDialog.getByRole('button', { name: 'Do not show again' });
await playExpect(doNotshowButton).toBeVisible();
const cancelButton = updateAvailableDialog.getByRole('button', { name: 'Cancel' });
await playExpect(cancelButton).toBeVisible();
await cancelButton.click();
await playExpect(updateAvailableDialog).not.toBeVisible();
// handle welcome page now
await welcomePage.handleWelcomePage(true);
});

test('Version button is visible', async () => {
await playExpect(sBar.content).toBeVisible();
await playExpect(sBar.versionButton).toBeVisible();
});

test('User initiated update option is available', async ({ page }) => {
await playExpect(sBar.updateButtonTitle).toHaveText(await sBar.versionButton.innerText());
await sBar.updateButtonTitle.click();
await handleConfirmationDialog(page, 'Update Available now', false, '', 'Cancel');
});
});
test.describe.serial('Podman Desktop Update installation can be performed', () => {
test.skip(!performUpdate, 'Update test does not run as UPDATE_PODMAN_DESKTOP env. var. is not set');
test('Update can be initiated', async () => {
await sBar.updateButtonTitle.click();
await playExpect(updateAvailableDialog).toBeVisible();
const updateNowButton = updateAvailableDialog.getByRole('button', { name: 'Update now' });
await playExpect(updateNowButton).toBeVisible();
await updateNowButton.click();
await playExpect(updateAvailableDialog).not.toBeVisible();
});

test('Update is in progress', async ({ page }) => {
await sBar.updateButtonTitle.click();
await playExpect(updateDialog).toBeVisible();
await handleConfirmationDialog(page, 'Update', true, 'OK', 'Cancel');
});

test('Update is performed and restart offered', async ({ page }) => {
test.setTimeout(150000);
// now it takes some time to perform, in case of failure, PD gets closed
await playExpect(updateDownloadedDialog).toBeVisible({ timeout: 120000 });
// some buttons
await handleConfirmationDialog(page, 'Update Downloaded', false, 'Restart', 'Cancel');
});
});
6 changes: 6 additions & 0 deletions tests/playwright/src/utility/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { test as base } from '@playwright/test';

import { WelcomePage } from '../model/pages/welcome-page';
import { NavigationBar } from '../model/workbench/navigation';
import { StatusBar } from '../model/workbench/status-bar';
import { Runner } from '../runner/podman-desktop-runner';
import { RunnerOptions } from '../runner/runner-options';

Expand All @@ -29,6 +30,7 @@ export type TestFixtures = {
navigationBar: NavigationBar;
welcomePage: WelcomePage;
page: Page;
statusBar: StatusBar;
};

export type FixtureOptions = {
Expand All @@ -52,5 +54,9 @@ export const test = base.extend<TestFixtures & FixtureOptions>({
const welcomePage = new WelcomePage(page);
await use(welcomePage);
},
statusBar: async ({ page }, use) => {
const statusBar = new StatusBar(page);
await use(statusBar);
},
});
export { expect } from '@playwright/test';
3 changes: 2 additions & 1 deletion tests/playwright/src/utility/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,11 @@ export async function handleConfirmationDialog(
): Promise<void> {
// wait for dialog to appear using waitFor
const dialog = page.getByRole('dialog', { name: dialogTitle, exact: true });
await dialog.waitFor({ state: 'visible', timeout: 3000 });
await playExpect(dialog).toBeVisible();
const button = confirm
? dialog.getByRole('button', { name: confirmationButton })
: dialog.getByRole('button', { name: cancelButton });
await playExpect(button).toBeEnabled();
await button.click();
}

Expand Down

0 comments on commit 4e583e9

Please sign in to comment.