Skip to content

Commit 53e6511

Browse files
committed
chore(tests): compose onboarding e2e tests added
Signed-off-by: Tamara Babalova <[email protected]>
1 parent defc465 commit 53e6511

File tree

5 files changed

+204
-1
lines changed

5 files changed

+204
-1
lines changed

packages/renderer/src/lib/preferences/PreferencesCliTool.svelte

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function getLoggerHandler(_cliToolId: string): ConnectionCallback {
4949
}
5050
</script>
5151

52-
<div role="row" class="bg-charcoal-600 mb-5 rounded-md p-3 flex flex-col">
52+
<div role="row" class="bg-charcoal-600 mb-5 rounded-md p-3 flex flex-col" aria-label="{cliTool.displayName}">
5353
<div class="divide-x divide-gray-900 flex flex-row">
5454
<div>
5555
<!-- left col - cli-tool icon/name + "create new" button -->
+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/**********************************************************************
2+
* Copyright (C) 2024 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import { expect as playExpect } from '@playwright/test';
20+
import type { Page } from '@playwright/test';
21+
import { PodmanDesktopRunner } from './runner/podman-desktop-runner';
22+
import { afterAll, beforeAll, beforeEach, test, describe } from 'vitest';
23+
import { WelcomePage } from './model/pages/welcome-page';
24+
import { NavigationBar } from './model/workbench/navigation';
25+
import type { RunnerTestContext } from './testContext/runner-test-context';
26+
import { SettingsBar } from './model/pages/settings-bar';
27+
import { ResourcesPage } from './model/pages/resources-page';
28+
import { ComposeOnboardingPage } from './model/pages/compose-onboarding-page';
29+
import { CLIToolsPage } from './model/pages/cli-tools-page';
30+
31+
let pdRunner: PodmanDesktopRunner;
32+
let page: Page;
33+
let navBar: NavigationBar;
34+
let composeVersion: string;
35+
36+
beforeAll(async () => {
37+
pdRunner = new PodmanDesktopRunner();
38+
page = await pdRunner.start();
39+
pdRunner.setVideoAndTraceName('compose-onboarding-e2e');
40+
41+
const welcomePage = new WelcomePage(page);
42+
await welcomePage.handleWelcomePage(true);
43+
navBar = new NavigationBar(page);
44+
});
45+
46+
afterAll(async () => {
47+
await pdRunner.close();
48+
});
49+
50+
beforeEach<RunnerTestContext>(async ctx => {
51+
ctx.pdRunner = pdRunner;
52+
});
53+
54+
describe('Compose onboarding workflow verification', async () => {
55+
test('Can enter Compose onboarding', async () => {
56+
await navBar.openSettings();
57+
const settingsBar = new SettingsBar(page);
58+
const resourcesPage = await settingsBar.openTabPage(ResourcesPage);
59+
60+
const composeBox = resourcesPage.featuredProviderResources.getByRole('region', { name: 'Compose' });
61+
await playExpect(composeBox).toBeVisible();
62+
await composeBox.scrollIntoViewIfNeeded();
63+
64+
const setupButton = composeBox.getByRole('button', { name: 'Setup Compose' });
65+
await playExpect(setupButton).toBeVisible({ timeout: 50000 });
66+
67+
await setupButton.click();
68+
69+
const onboardingPage = new ComposeOnboardingPage(page);
70+
71+
await playExpect(onboardingPage.heading).toBeVisible();
72+
await playExpect(onboardingPage.statusMessage).toHaveText('Compose Download');
73+
74+
const downloadAvailableText = page.getByText(
75+
/Compose will be downloaded in the next step \(Version v[0-9.]+\). Want to download/,
76+
{ exact: true },
77+
);
78+
await playExpect(downloadAvailableText).toBeVisible();
79+
80+
const versionInfoFullText = await downloadAvailableText.textContent();
81+
const matches = versionInfoFullText?.match(/v\d+(\.\d+)+/);
82+
if (matches) {
83+
composeVersion = matches[0];
84+
}
85+
});
86+
87+
test('Can install Compose locally', async () => {
88+
const onboardingPage = new ComposeOnboardingPage(page);
89+
await onboardingPage.nextButton.click();
90+
91+
await playExpect(onboardingPage.statusMessage).toHaveText('Compose Successfully Downloaded', { timeout: 50000 });
92+
93+
await onboardingPage.cancelButton.click();
94+
95+
const skipDialog = page.getByRole('dialog', { name: 'Skip Setup Popup', exact: true });
96+
const skipOkButton = skipDialog.getByRole('button', { name: 'Ok' });
97+
await skipOkButton.click();
98+
});
99+
100+
test('Can install Compose system-wide', async () => {
101+
const resourcesPage = new ResourcesPage(page);
102+
const composeBox = resourcesPage.featuredProviderResources.getByRole('region', { name: 'Compose' });
103+
const setupButton = composeBox.getByRole('button', { name: 'Setup Compose' });
104+
await setupButton.click();
105+
106+
const onboardingPage = new ComposeOnboardingPage(page);
107+
await playExpect(onboardingPage.statusMessage).toHaveText('Compose Successfully Downloaded');
108+
const downloadAvailableText = page.getByText(
109+
'The next step will install Compose system-wide. You will be prompted for system',
110+
);
111+
await playExpect(downloadAvailableText).toBeVisible();
112+
113+
await onboardingPage.nextButton.click();
114+
115+
await playExpect(onboardingPage.statusMessage).toHaveText('Compose Installed', { timeout: 50000 });
116+
let downloadFinishedText = page.locator('p');
117+
downloadFinishedText = downloadFinishedText.filter({ hasText: 'Compose is installed system-wide!' });
118+
await playExpect(downloadFinishedText).toBeVisible();
119+
120+
await onboardingPage.nextButton.click();
121+
});
122+
123+
test('Verify Compose was installed', async () => {
124+
const resourcesPage = new ResourcesPage(page);
125+
const composeBox = resourcesPage.featuredProviderResources.getByRole('region', { name: 'Compose' });
126+
const setupButton = composeBox.getByRole('button', { name: 'Setup Compose' });
127+
await playExpect(setupButton).toBeHidden();
128+
129+
const settingsBar = new SettingsBar(page);
130+
const cliToolsPage = await settingsBar.openTabPage(CLIToolsPage);
131+
const composeRow = cliToolsPage.toolsTable.getByLabel('Compose');
132+
const composeVersionInfo = composeRow.getByLabel('cli-version');
133+
await playExpect(composeVersionInfo).toHaveText('docker-compose ' + composeVersion);
134+
});
135+
});
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**********************************************************************
2+
* Copyright (C) 2024 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import type { Locator, Page } from 'playwright';
20+
import { SettingsPage } from './settings-page';
21+
22+
export class CLIToolsPage extends SettingsPage {
23+
readonly heading: Locator;
24+
readonly toolsTable: Locator;
25+
26+
constructor(page: Page) {
27+
super(page, 'CLI Tools');
28+
this.heading = page.getByRole('heading', { name: 'CLI Tools' });
29+
this.toolsTable = page.getByRole('table', { name: 'cli-tools' });
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**********************************************************************
2+
* Copyright (C) 2024 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
import type { Locator, Page } from 'playwright';
20+
import { SettingsPage } from './settings-page';
21+
22+
export class ComposeOnboardingPage extends SettingsPage {
23+
readonly heading: Locator;
24+
readonly statusMessage: Locator;
25+
readonly cancelButton: Locator;
26+
readonly nextButton: Locator;
27+
28+
constructor(page: Page) {
29+
super(page, 'Compose Setup');
30+
this.heading = page.getByRole('heading', { name: 'Compose Setup Header' });
31+
this.statusMessage = page.getByLabel('Onboarding Status Message');
32+
this.cancelButton = page.getByRole('button', { name: 'Cancel Setup' });
33+
this.nextButton = page.getByRole('button', { name: 'Next Step' });
34+
}
35+
}

tests/src/model/pages/settings-bar.ts

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export class SettingsBar {
3030
readonly extensionsTab: Locator;
3131
readonly desktopExtensionsTab: Locator;
3232
readonly preferencesTab: Locator;
33+
readonly cliToolsTab: Locator;
3334

3435
constructor(page: Page) {
3536
this.page = page;
@@ -41,6 +42,7 @@ export class SettingsBar {
4142
this.extensionsTab = this.settingsNavBar.getByRole('link', { name: 'Extensions', exact: true });
4243
this.desktopExtensionsTab = this.settingsNavBar.getByRole('link', { name: 'DesktopExtensions' });
4344
this.preferencesTab = this.settingsNavBar.getByRole('link', { name: 'preferences' });
45+
this.cliToolsTab = this.settingsNavBar.getByRole('link', { name: 'CLI Tools' });
4446
}
4547

4648
public async openTabPage<T extends SettingsPage>(type: new (page: Page) => T): Promise<T> {

0 commit comments

Comments
 (0)