mirror of
https://github.com/podman-desktop/podman-desktop
synced 2026-04-21 09:37:22 +00:00
chore(test): refactoring of runner factory class (#17045)
* chore(test): refactoring of runner factory class
This commit is contained in:
parent
a0191823a1
commit
0eaf131dd6
5 changed files with 63 additions and 41 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -16,3 +16,4 @@ yarn.lock
|
|||
extensions/podman/assets/
|
||||
extensions-extra/
|
||||
__mocks__/@podman-desktop/api.ts
|
||||
contexts/meta/
|
||||
|
|
|
|||
|
|
@ -23,10 +23,9 @@ import type { ElectronApplication, JSHandle, Page } from '@playwright/test';
|
|||
import { _electron as electron } from '@playwright/test';
|
||||
import type { BrowserWindow } from 'electron';
|
||||
|
||||
import { Runner } from '/@/runner/podman-desktop-runner';
|
||||
import { RunnerFactory } from '/@/runner/runner-factory';
|
||||
|
||||
import { Runner } from './podman-desktop-runner';
|
||||
import type { RunnerOptions } from './runner-options';
|
||||
import type { RunnerOptions } from '/@/runner/runner-options';
|
||||
|
||||
type WindowState = {
|
||||
isVisible: boolean;
|
||||
|
|
|
|||
|
|
@ -15,42 +15,58 @@
|
|||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
***********************************************************************/
|
||||
/** biome-ignore-all lint/complexity/noStaticOnlyClass: <Singleton pattern> */
|
||||
import { ChromeDevToolsProtocolRunner } from '/@/runner/chrome-dev-tools-protocol-runner';
|
||||
import { ElectronRunner } from '/@/runner/electron-runner';
|
||||
import type { Runner } from '/@/runner/podman-desktop-runner';
|
||||
import { RunnerOptions } from '/@/runner/runner-options';
|
||||
|
||||
export class RunnerFactory {
|
||||
protected static _instance: Runner | undefined;
|
||||
private static _instance: Runner | undefined;
|
||||
private static _initializing: Promise<Runner> | undefined;
|
||||
|
||||
static async getInstance({
|
||||
runnerOptions = new RunnerOptions(),
|
||||
}: {
|
||||
runnerOptions?: RunnerOptions;
|
||||
} = {}): Promise<Runner> {
|
||||
if (!this._instance) {
|
||||
const pdArgs = process.env.PODMAN_DESKTOP_ARGS;
|
||||
const pdBinary = process.env.PODMAN_DESKTOP_BINARY;
|
||||
const debugPort = process.env.DEBUGGING_PORT;
|
||||
if (
|
||||
(pdArgs && !pdBinary && !debugPort) ||
|
||||
(pdBinary && !pdArgs && !debugPort) ||
|
||||
(!pdArgs && !pdBinary && !debugPort)
|
||||
) {
|
||||
this._instance = new ElectronRunner({ runnerOptions });
|
||||
} else if (pdBinary && debugPort) {
|
||||
this._instance = new ChromeDevToolsProtocolRunner({ runnerOptions });
|
||||
} else {
|
||||
throw new Error(
|
||||
'Allowed combinations are standalone PODMAN_DESKTOP_ARGS or PODMAN_DESKTOP_BINARY or neither of them for electron runner. Or PODMAN_DESKTOP_BINARY and DEBUGGING_PORT for CDP runner...',
|
||||
);
|
||||
}
|
||||
await this._instance.start();
|
||||
static async getInstance(runnerOptions?: RunnerOptions): Promise<Runner> {
|
||||
if (RunnerFactory._instance) return RunnerFactory._instance;
|
||||
if (RunnerFactory._initializing) return RunnerFactory._initializing;
|
||||
|
||||
RunnerFactory._initializing = RunnerFactory.create(runnerOptions ?? new RunnerOptions());
|
||||
try {
|
||||
RunnerFactory._instance = await RunnerFactory._initializing;
|
||||
return RunnerFactory._instance;
|
||||
} finally {
|
||||
RunnerFactory._initializing = undefined;
|
||||
}
|
||||
return this._instance;
|
||||
}
|
||||
|
||||
private static async create(runnerOptions: RunnerOptions): Promise<Runner> {
|
||||
const runner = RunnerFactory.resolveRunner(runnerOptions);
|
||||
await runner.start();
|
||||
return runner;
|
||||
}
|
||||
|
||||
private static resolveRunner(runnerOptions: RunnerOptions): Runner {
|
||||
const pdArgs = process.env.PODMAN_DESKTOP_ARGS;
|
||||
const pdBinary = process.env.PODMAN_DESKTOP_BINARY;
|
||||
const debugPort = process.env.DEBUGGING_PORT;
|
||||
|
||||
if (pdArgs && pdBinary) {
|
||||
throw new Error('PODMAN_DESKTOP_ARGS and PODMAN_DESKTOP_BINARY are mutually exclusive');
|
||||
}
|
||||
if (pdArgs && debugPort) {
|
||||
throw new Error('DEBUGGING_PORT requires PODMAN_DESKTOP_BINARY, not PODMAN_DESKTOP_ARGS');
|
||||
}
|
||||
if (debugPort && !pdBinary) {
|
||||
throw new Error('DEBUGGING_PORT requires PODMAN_DESKTOP_BINARY to be set');
|
||||
}
|
||||
|
||||
if (pdBinary && debugPort) {
|
||||
return new ChromeDevToolsProtocolRunner({ runnerOptions });
|
||||
}
|
||||
return new ElectronRunner({ runnerOptions });
|
||||
}
|
||||
|
||||
static dispose(): void {
|
||||
this._instance = undefined;
|
||||
RunnerFactory._instance = undefined;
|
||||
RunnerFactory._initializing = undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,18 +116,24 @@ test.describe
|
|||
await playExpect(imagesPage.heading).toBeVisible({ timeout: 5_000 });
|
||||
await navigationBar.goBack(); // Now on Containers with forward available
|
||||
await playExpect(containerPage.heading).toBeVisible({ timeout: 5_000 });
|
||||
// Simulate trackpad swipe left (deltaX > 30 for forward)
|
||||
await page.evaluate(() => {
|
||||
const event = new WheelEvent('wheel', {
|
||||
deltaX: 50, // > 30 threshold for forward navigation
|
||||
deltaY: 0,
|
||||
bubbles: true,
|
||||
});
|
||||
document.body.dispatchEvent(event);
|
||||
});
|
||||
|
||||
// Verify navigation to Images
|
||||
await playExpect(imagesPage.heading).toBeVisible({ timeout: 5_000 });
|
||||
const forwardButton = page.getByRole('button', { name: 'Forward (hold for history)' });
|
||||
await playExpect(forwardButton).toBeEnabled({ timeout: 5_000 });
|
||||
|
||||
// The app has a 500ms swipe cooldown (NavigationButtons.handleWheel) that may
|
||||
// still be active from the previous trackpad-swipe-left test. Poll the dispatch
|
||||
// so the event is retried once the cooldown expires.
|
||||
await playExpect
|
||||
.poll(
|
||||
async () => {
|
||||
await page.evaluate(() => {
|
||||
document.body.dispatchEvent(new WheelEvent('wheel', { deltaX: 50, deltaY: 0, bubbles: true }));
|
||||
});
|
||||
return imagesPage.heading.isVisible();
|
||||
},
|
||||
{ timeout: 5_000 },
|
||||
)
|
||||
.toBeTruthy();
|
||||
});
|
||||
|
||||
test('Navigation shortcuts blocked when focus in input field', async ({ navigationBar, page }) => {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export type FixtureOptions = {
|
|||
export const test = base.extend<TestFixtures & FixtureOptions>({
|
||||
runnerOptions: [new RunnerOptions(), { option: true }],
|
||||
runner: async ({ runnerOptions }, use) => {
|
||||
const runner = await RunnerFactory.getInstance({ runnerOptions });
|
||||
const runner = await RunnerFactory.getInstance(runnerOptions);
|
||||
await use(runner);
|
||||
},
|
||||
page: async ({ runner }, use) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue