Skip to content

Commit 0414687

Browse files
authored
Creating rhel vm machine e2e (#139)
* chore(test): initial draft for e2e test
1 parent becfad4 commit 0414687

1 file changed

Lines changed: 186 additions & 18 deletions

File tree

tests/playwright/src/rhel-extension.spec.ts

Lines changed: 186 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,27 @@
1616
* SPDX-License-Identifier: Apache-2.0
1717
***********************************************************************/
1818

19-
import type { NavigationBar } from '@podman-desktop/tests-playwright';
19+
import * as path from 'node:path';
20+
import { fileURLToPath } from 'node:url';
21+
22+
import type { Browser, Locator, Page } from '@playwright/test';
23+
import type { ConfirmInputValue } from '@podman-desktop/tests-playwright';
2024
import {
25+
AuthenticationPage,
2126
expect as playExpect,
27+
findPageWithTitleInBrowser,
28+
getEntryFromLogs,
29+
NavigationBar,
30+
performBrowserLogin,
31+
ResourceConnectionCardPage,
32+
ResourceElementActions,
33+
ResourceElementState,
34+
ResourcesPage,
2235
RunnerOptions,
36+
startChromium,
2337
test,
2438
waitForPodmanMachineStartup,
39+
waitUntil,
2540
} from '@podman-desktop/tests-playwright';
2641

2742
const extensionName = 'rhel-vms';
@@ -31,6 +46,17 @@ let extensionInstalled = false;
3146
const skipInstallation = process.env.SKIP_INSTALLATION;
3247
const extensionURL = process.env.OCI_IMAGE ?? 'ghcr.io/redhat-developer/podman-desktop-rhel-ext:next';
3348

49+
const __filename = fileURLToPath(import.meta.url);
50+
const __dirname = path.dirname(__filename);
51+
const browserOutputPath = [__dirname, '..', 'output', 'browser'];
52+
53+
const expectedAuthPageTitle = 'Log In';
54+
const regex = new RegExp(/((http|https):\/\/.*$)/);
55+
let signInButton: Locator;
56+
let browser: Browser;
57+
let chromiumPage: Page;
58+
const chromePort = '9222';
59+
3460
test.use({
3561
runnerOptions: new RunnerOptions({
3662
customFolder: 'rhel-e2e-tests',
@@ -51,29 +77,146 @@ test.afterAll(async ({ runner }) => {
5177
});
5278

5379
test.describe.serial('RHEL Extension E2E Tests', () => {
54-
test.describe.configure({ retries: 1 });
55-
test('Go to settings and check if extension is already installed', async ({ navigationBar }) => {
56-
const extensionsPage = await navigationBar.openExtensions();
57-
if (await extensionsPage.extensionIsInstalled(extensionLabel)) extensionInstalled = true;
80+
test.describe.serial('Authentication Extension', () => {
81+
test('Go to settings and check if extension is already installed', async ({ navigationBar }) => {
82+
const extensionsPage = await navigationBar.openExtensions();
83+
if (await extensionsPage.extensionIsInstalled(extensionLabel)) extensionInstalled = true;
84+
});
85+
86+
test('Uninstalled previous version of rhel extension', async ({ navigationBar }) => {
87+
test.skip(!extensionInstalled || !!skipInstallation);
88+
test.setTimeout(120_000);
89+
console.log('Extension found already installed, trying to remove!');
90+
await ensureRhelExtensionIsRemoved(navigationBar);
91+
});
92+
93+
test('Install extension through Extension page', async ({ navigationBar }) => {
94+
test.skip(!!skipInstallation);
95+
test.setTimeout(200_000);
96+
97+
const extensionsPage = await navigationBar.openExtensions();
98+
await extensionsPage.installExtensionFromOCIImage(extensionURL);
99+
100+
await playExpect
101+
.poll(async () => await extensionsPage.extensionIsInstalled(extensionLabel), { timeout: 30_000 })
102+
.toBeTruthy();
103+
});
58104
});
59105

60-
test('Uninstalled previous version of rhel extension', async ({ navigationBar }) => {
61-
test.skip(!extensionInstalled || !!skipInstallation);
62-
test.setTimeout(120_000);
63-
console.log('Extension found already installed, trying to remove!');
64-
await ensureRhelExtensionIsRemoved(navigationBar);
106+
test.describe.serial('Red Hat Authentication extension installation', () => {
107+
test('SSO provider is available in Authentication Page', async ({ page, navigationBar }) => {
108+
const settingsBar = await navigationBar.openSettings();
109+
await settingsBar.openTabPage(AuthenticationPage);
110+
111+
const authPage = new AuthenticationPage(page);
112+
await playExpect(authPage.heading).toBeVisible({ timeout: 10_000 });
113+
114+
signInButton = page.getByRole('button', { name: 'Sign in' });
115+
await playExpect(signInButton).toBeVisible();
116+
});
117+
118+
test('Can open authentication page in browser', async ({ navigationBar, page }) => {
119+
test.setTimeout(120_000);
120+
const settingsBar = await navigationBar.openSettings();
121+
await settingsBar.openTabPage(AuthenticationPage);
122+
const authPage = new AuthenticationPage(page);
123+
await playExpect(authPage.heading).toBeVisible({ timeout: 10_000 });
124+
125+
// start up chrome instance and return browser object
126+
browser = await startChromium(chromePort, path.join(...browserOutputPath));
127+
128+
// open the link from PD
129+
await page.bringToFront();
130+
131+
await playExpect(signInButton).toBeEnabled({ timeout: 10_000 });
132+
await signInButton.click();
133+
134+
await page.waitForTimeout(5_000);
135+
136+
const urlMatch = await getEntryFromLogs(page, /\.*openid-connect.*/, regex, 'sso.redhat.com');
137+
if (urlMatch) {
138+
const context = await browser.newContext();
139+
const newPage = await context.newPage();
140+
await newPage.goto(urlMatch);
141+
await newPage.waitForURL(/sso.redhat.com/);
142+
chromiumPage = newPage;
143+
const page = await findPageWithTitleInBrowser(browser, expectedAuthPageTitle);
144+
console.log(`Found page with title: ${await page?.title()}`);
145+
} else {
146+
throw new Error('Did not find Initial SSO Login Page');
147+
}
148+
});
149+
150+
test('User can authenticate via browser', async () => {
151+
// Activate the browser window and perform login
152+
playExpect(chromiumPage).toBeDefined();
153+
if (!chromiumPage) {
154+
throw new Error('Chromium browser page was not initialized');
155+
}
156+
await chromiumPage.bringToFront();
157+
console.log(`Switched to Chrome tab with title: ${await chromiumPage.title()}`);
158+
const usernameAction: ConfirmInputValue = {
159+
inputLocator: chromiumPage.getByRole('textbox', { name: 'Red Hat login or email' }),
160+
inputValue: process.env.DVLPR_USERNAME ?? 'unknown',
161+
confirmLocator: chromiumPage.getByRole('button', { name: 'Next' }),
162+
};
163+
const passwordAction: ConfirmInputValue = {
164+
inputLocator: chromiumPage.getByRole('textbox', { name: 'Password' }),
165+
inputValue: process.env.DVLPR_PASSWORD ?? 'unknown',
166+
confirmLocator: chromiumPage.getByRole('button', { name: 'Log in' }),
167+
};
168+
await performBrowserLogin(chromiumPage, /Log In/, usernameAction, passwordAction, async chromiumPage => {
169+
const backButton = chromiumPage.getByRole('button', { name: 'Go back to Podman Desktop' });
170+
await playExpect(backButton).toBeEnabled();
171+
await backButton.click();
172+
});
173+
await chromiumPage.close();
174+
});
65175
});
66176

67-
test('Install extension through Extension page', async ({ navigationBar }) => {
68-
test.skip(!!skipInstallation);
69-
test.setTimeout(200_000);
177+
test.describe.serial('RHEL VMs Extension', () => {
178+
test('Create RHEL VM', async ({ page }) => {
179+
test.setTimeout(310_000);
180+
await createRhelVM(page, 300_000);
181+
182+
const resourcesPage = new ResourcesPage(page);
183+
await playExpect(resourcesPage.heading).toBeVisible({ timeout: 10_000 });
184+
185+
const machineCard = new ResourceConnectionCardPage(page, 'macadam', 'rhel');
186+
await playExpect.poll(async () => machineCard.doesResourceElementExist(), { timeout: 30_000 }).toBeTruthy();
187+
playExpect(await machineCard.resourceElementConnectionStatus.innerText()).toContain(ResourceElementState.Off);
188+
});
189+
190+
test('Start RHEL VM', async ({ page }) => {
191+
test.setTimeout(70_000);
192+
const machineCard = new ResourceConnectionCardPage(page, 'macadam', 'rhel');
193+
await machineCard.performConnectionAction(ResourceElementActions.Start);
194+
195+
await waitUntil(
196+
async () =>
197+
(await machineCard.resourceElementConnectionStatus.innerText()).includes(ResourceElementState.Running),
198+
{ timeout: 60_000, sendError: true },
199+
);
200+
});
201+
202+
test('Stop RHEL VM', async ({ page }) => {
203+
test.setTimeout(70_000);
204+
const machineCard = new ResourceConnectionCardPage(page, 'macadam', 'rhel');
205+
await machineCard.performConnectionAction(ResourceElementActions.Stop);
206+
207+
await waitUntil(
208+
async () => (await machineCard.resourceElementConnectionStatus.innerText()).includes(ResourceElementState.Off),
209+
{ timeout: 30_000, sendError: true },
210+
);
211+
});
70212

71-
const extensionsPage = await navigationBar.openExtensions();
72-
await extensionsPage.installExtensionFromOCIImage(extensionURL);
213+
test('Remove RHEL VM', async ({ page }) => {
214+
test.setTimeout(70_000);
215+
const machineCard = new ResourceConnectionCardPage(page, 'macadam', 'rhel');
216+
await machineCard.performConnectionAction(ResourceElementActions.Delete);
73217

74-
await playExpect
75-
.poll(async () => await extensionsPage.extensionIsInstalled(extensionLabel), { timeout: 30_000 })
76-
.toBeTruthy();
218+
await playExpect.poll(async () => machineCard.doesResourceElementExist(), { timeout: 30_000 }).toBeFalsy();
219+
});
77220
});
78221

79222
test('Remove RHEL extension through Settings', async ({ navigationBar }) => {
@@ -99,3 +242,28 @@ async function ensureRhelExtensionIsRemoved(navigationBar: NavigationBar): Promi
99242
.poll(async () => await extensionsPage.extensionIsInstalled(extensionLabel), { timeout: 30_000 })
100243
.toBeFalsy();
101244
}
245+
246+
async function createRhelVM(page: Page, timeout = 120_000): Promise<void> {
247+
const navigationBar = new NavigationBar(page);
248+
const rhelResourceCard = new ResourceConnectionCardPage(page, 'macadam');
249+
250+
const settingsPage = await navigationBar.openSettings();
251+
const resourcesPage = await settingsPage.openTabPage(ResourcesPage);
252+
await playExpect(resourcesPage.heading).toBeVisible({ timeout: 10_000 });
253+
await playExpect.poll(async () => resourcesPage.resourceCardIsVisible('macadam')).toBeTruthy();
254+
await playExpect(rhelResourceCard.createButton).toBeVisible();
255+
256+
await rhelResourceCard.createButton.click();
257+
258+
const rhelVMNameInput = page.getByLabel('Machine Name', { exact: true });
259+
await playExpect(rhelVMNameInput).toBeVisible({ timeout: 10_000 });
260+
await playExpect(rhelVMNameInput).toHaveValue('rhel');
261+
262+
const createRhelVMButton = page.getByRole('button', { name: 'Create', exact: true });
263+
await playExpect(createRhelVMButton).toBeEnabled({ timeout: 10_000 });
264+
await createRhelVMButton.click();
265+
266+
const goBackButton = page.getByRole('button', { name: 'Go back to resources' });
267+
await playExpect(goBackButton).toBeEnabled({ timeout: timeout });
268+
await goBackButton.click();
269+
}

0 commit comments

Comments
 (0)