Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update e2e test to pnpm #1

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 12 additions & 18 deletions .github/workflows/pr-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ jobs:
- uses: actions/checkout@v4
with:
path: podman-desktop-extension-bootc

- uses: actions/setup-node@v4
with:
node-version: 20
Expand Down Expand Up @@ -128,24 +129,19 @@ jobs:
# allow unprivileged user namespace
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

- name: Build Podman Desktop for E2E tests
working-directory: ./podman-desktop
run: |
yarn --frozen-lockfile
yarn test:e2e:build
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
run_install: false
package_json_file: ./podman-desktop/package.json

- name: Get yarn cache directory path
working-directory: ./podman-desktop-extension-bootc
id: yarn-cache-dir-path
run: echo "dir=$(yarn cache dir)" >> ${GITHUB_OUTPUT}
- name: Execute pnpm
working-directory: ./podman-desktop
run: pnpm install

- uses: actions/cache@v4
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Build Podman Desktop for E2E tests
working-directory: ./podman-desktop
run: pnpm test:e2e:build

- name: Ensure getting current HEAD version of the test framework
working-directory: ./podman-desktop-extension-bootc/tests/playwright
Expand Down Expand Up @@ -180,5 +176,3 @@ jobs:
with:
name: e2e-tests
path: ./**/tests/output/


5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"resolutions": {
"string-width": "^4.2.0",
"wrap-ansi": "^7.0.0"
},
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^8.3.0",
"@typescript-eslint/parser": "^8.0.1",
Expand Down Expand Up @@ -62,5 +62,6 @@
},
"dependencies": {
"js-yaml": "^4.1.0"
}
},
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
2 changes: 1 addition & 1 deletion tests/playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Podman Desktop BootC extension Playwright E2E tests",
"scripts": {
"test:e2e:setup": "xvfb-maybe --auto-servernum --server-args='-screen 0 1280x960x24' --",
"test:e2e": "npm run test:e2e:setup vitest run src/ --pool=threads --poolOptions.threads.singleThread --poolOptions.threads.isolate --no-file-parallelism"
"test:e2e": "npm run test:e2e:setup npx playwright test src/"
},
"author": "Red Hat",
"license": "Apache-2.0",
Expand Down
40 changes: 40 additions & 0 deletions tests/playwright/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**********************************************************************
* Copyright (C) 2024 Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-License-Identifier: Apache-2.0
***********************************************************************/

import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
outputDir: 'tests/playwright/output/',
workers: 1,

reporter: [
['list'],
['junit', { outputFile: 'tests/playwright/output/junit-results.xml' }],
['json', { outputFile: 'tests/playwright/output/json-results.json' }],
['html', { open: 'never', outputFolder: 'tests/playwright/output/html-results/' }],
],

projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
],
});
164 changes: 80 additions & 84 deletions tests/playwright/src/bootc-extension.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
***********************************************************************/

import type { Page } from '@playwright/test';
import { afterAll, beforeAll, test, describe, beforeEach } from 'vitest';
import {
NavigationBar,
PodmanDesktopRunner,
Expand All @@ -26,8 +25,7 @@ import {
removeFolderIfExists,
waitForPodmanMachineStartup,
} from '@podman-desktop/tests-playwright';
import { expect as playExpect } from '@playwright/test';
import { RunnerTestContext } from '@podman-desktop/tests-playwright';
import { expect as playExpect, test } from '@playwright/test';
import * as path from 'node:path';
import * as os from 'node:os';
import { BootcPage } from './model/bootc-page';
Expand All @@ -52,11 +50,7 @@ const buildISOImage = process.env.BUILD_ISO_IMAGE;
let timeoutForBuild = 900000;
let imageBuildFailed = true;

beforeEach<RunnerTestContext>(async ctx => {
ctx.pdRunner = pdRunner;
});

beforeAll(async () => {
test.beforeAll(async () => {
await removeFolderIfExists('tests/output/images');
pdRunner = new PodmanDesktopRunner({ customFolder: 'bootc-tests-pd', autoUpdate: false, autoCheckUpdate: false });
page = await pdRunner.start();
Expand All @@ -68,7 +62,8 @@ beforeAll(async () => {
await waitForPodmanMachineStartup(page);
});

afterAll(async () => {
test.afterAll(async () => {
test.setTimeout(180000);
try {
await deleteImage(page, imageName);
} catch (error) {
Expand All @@ -77,40 +72,38 @@ afterAll(async () => {
await removeFolderIfExists('tests/output/images');
await pdRunner.close();
}
}, 180000);
});

describe('BootC Extension', async () => {
test.describe.serial('BootC Extension', () => {
test('Go to settings and check if extension is already installed', async () => {
const extensionsPage = await navBar.openExtensions();
if (await extensionsPage.extensionIsInstalled(extensionLabel)) extensionInstalled = true;
});

test.runIf(extensionInstalled && !skipInstallation)(
'Uninstalled previous version of bootc extension',
async () => {
console.log('Extension found already installed, trying to remove!');
await ensureBootcIsRemoved();
},
200000,
);

test.runIf(!skipInstallation)(
'Install extension through Extension page',
async () => {
const extensionsPage = await navBar.openExtensions();
await extensionsPage.installExtensionFromOCIImage('ghcr.io/containers/podman-desktop-extension-bootc');

await playExpect
.poll(async () => await extensionsPage.extensionIsInstalled(extensionLabel), { timeout: 30000 })
.toBeTruthy();
},
200000,
);

describe.each([ArchitectureType.ARM64, ArchitectureType.AMD64])(
'Bootc images for architecture: %s',
async architecture => {
test('Uninstalled previous version of bootc extension', async () => {
test.skip(!extensionInstalled && !!skipInstallation);
test.setTimeout(200000);
console.log('Extension found already installed, trying to remove!');
await ensureBootcIsRemoved();
});

test('Install extension through Extension page', async () => {
test.skip(!!skipInstallation);
test.setTimeout(200000);
const extensionsPage = await navBar.openExtensions();
await extensionsPage.installExtensionFromOCIImage('ghcr.io/containers/podman-desktop-extension-bootc');

await playExpect
.poll(async () => await extensionsPage.extensionIsInstalled(extensionLabel), { timeout: 30000 })
.toBeTruthy();
});

const architecture = [ArchitectureType.ARM64, ArchitectureType.AMD64];

for (const arch of architecture) {
test.describe.serial('Bootc images for architecture: %s', () => {
test('Build bootc image from containerfile', async () => {
test.setTimeout(210000);
imageBuildFailed = true;
let imagesPage = await navBar.openImages();
await playExpect(imagesPage.heading).toBeVisible();
Expand All @@ -122,61 +115,64 @@ describe('BootC Extension', async () => {
`${imageName}:${imageTag}`,
containerFilePath,
contextDirectory,
architecture,
arch,
180000,
);

await playExpect.poll(async () => await imagesPage.waitForImageExists(imageName)).toBeTruthy();
imageBuildFailed = false;
}, 210000);

describe.skipIf(isLinux).each(['QCOW2', 'AMI', 'RAW', 'VMDK', 'ISO'])('Building images ', async type => {
test(`Building bootable image type: ${type}`, async context => {
if (imageBuildFailed) {
console.log('Image build failed, skipping test');
context.skip();
}

if (type === 'ISO') {
if (buildISOImage) {
timeoutForBuild = 1200000;
console.log(`Building ISO image requested, extending timeout to ${timeoutForBuild}`);
});

const types = ['QCOW2', 'AMI', 'RAW', 'VMDK', 'ISO'];
for (const type of types) {
test.describe.serial('Building images ', () => {
test.skip(isLinux);

test(`Building bootable image type: ${type}`, async () => {
test.skip(imageBuildFailed);
test.setTimeout(1250000);

if (type === 'ISO') {
if (buildISOImage) {
timeoutForBuild = 1200000;
console.log(`Building ISO image requested, extending timeout to ${timeoutForBuild}`);
} else {
console.log(`Building ISO image not requested, skipping test`);
test.skip();
}
}

const imagesPage = await navBar.openImages();
await playExpect(imagesPage.heading).toBeVisible();

const imageDetailPage = await imagesPage.openImageDetails(imageName);
await playExpect(imageDetailPage.heading).toBeVisible();

const pathToStore = path.resolve(__dirname, '..', 'tests', 'output', 'images', `${type}-${architecture}`);
[page, webview] = await handleWebview();
const bootcPage = new BootcPage(page, webview);
const result = await bootcPage.buildDiskImage(
`${imageName}:${imageTag}`,
pathToStore,
type,
arch,
timeoutForBuild,
);
console.log(
`Building disk image for platform ${os.platform()} and architecture ${architecture} and type ${type} is ${result}`,
);
if (isWindows && arch === ArchitectureType.ARM64) {
console.log('Expected to fail on Windows for ARM64');
playExpect(result).toBeFalsy();
} else {
console.log(`Building ISO image not requested, skipping test`);
context.skip();
console.log('Expected to pass on Linux, Windows and macOS');
playExpect(result).toBeTruthy();
}
}

const imagesPage = await navBar.openImages();
await playExpect(imagesPage.heading).toBeVisible();

const imageDetailPage = await imagesPage.openImageDetails(imageName);
await playExpect(imageDetailPage.heading).toBeVisible();

const pathToStore = path.resolve(__dirname, '..', 'tests', 'output', 'images', `${type}-${architecture}`);
[page, webview] = await handleWebview();
const bootcPage = new BootcPage(page, webview);
const result = await bootcPage.buildDiskImage(
`${imageName}:${imageTag}`,
pathToStore,
type,
architecture,
timeoutForBuild,
);
console.log(
`Building disk image for platform ${os.platform()} and architecture ${architecture} and type ${type} is ${result}`,
);
if (isWindows && architecture === ArchitectureType.ARM64) {
console.log('Expected to fail on Windows for ARM64');
playExpect(result).toBeFalsy();
} else {
console.log('Expected to pass on Linux, Windows and macOS');
playExpect(result).toBeTruthy();
}
}, 1250000);
});
},
);
});
});
}
});
}

test('Remove bootc extension through Settings', async () => {
await ensureBootcIsRemoved();
Expand Down
Loading