Skip to content

Commit 91e7e73

Browse files
committed
playwright: Add tests for Disk customization
1 parent 455ff8f commit 91e7e73

File tree

2 files changed

+300
-0
lines changed

2 files changed

+300
-0
lines changed
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
import * as fsPromises from 'fs/promises';
2+
import * as path from 'path';
3+
4+
import { expect } from '@playwright/test';
5+
import { v4 as uuidv4 } from 'uuid';
6+
7+
import { test } from '../fixtures/cleanup';
8+
import { isHosted } from '../helpers/helpers';
9+
import { ensureAuthenticated } from '../helpers/login';
10+
import {
11+
fillInImageOutput,
12+
ibFrame,
13+
navigateToLandingPage,
14+
} from '../helpers/navHelpers';
15+
import {
16+
createBlueprint,
17+
deleteBlueprint,
18+
exportBlueprint,
19+
fillInDetails,
20+
fillInImageOutputGuest,
21+
importBlueprint,
22+
registerLater,
23+
} from '../helpers/wizardHelpers';
24+
25+
test('Create a blueprint with Disk customization', async ({
26+
page,
27+
cleanup,
28+
}) => {
29+
const blueprintName = 'test-' + uuidv4();
30+
31+
// Delete the blueprint after the run fixture
32+
await cleanup.add(() => deleteBlueprint(page, blueprintName));
33+
34+
await ensureAuthenticated(page);
35+
36+
// Login, navigate to IB and get the frame
37+
await navigateToLandingPage(page);
38+
const frame = await ibFrame(page);
39+
40+
await test.step('Navigate to optional steps in Wizard', async () => {
41+
await fillInImageOutput(frame);
42+
await registerLater(frame);
43+
});
44+
45+
await test.step('Check basic structure of advanced partitioning', async () => {
46+
await frame
47+
.getByRole('button', { name: 'File system configuration' })
48+
.click();
49+
await frame
50+
.getByRole('radio', { name: 'Advanced disk partitioning' })
51+
.click();
52+
53+
const rawPartitioningRadio = frame.getByRole('radio', {
54+
name: /raw partitioning/i,
55+
});
56+
await expect(rawPartitioningRadio).toBeVisible();
57+
await expect(rawPartitioningRadio).toBeChecked();
58+
59+
await expect(frame.getByRole('button', { name: '/' })).toBeDisabled();
60+
await expect(
61+
frame.getByRole('row').nth(1).getByRole('button').nth(4),
62+
).toBeEnabled();
63+
64+
await expect(
65+
frame.getByRole('button', {
66+
name: /add plain partition/i,
67+
}),
68+
).toBeVisible();
69+
await expect(
70+
frame.getByRole('button', {
71+
name: /add lvm volume group/i,
72+
}),
73+
).toBeVisible();
74+
});
75+
76+
await test.step('Fill in some partitions and add a volume group', async () => {
77+
await frame.getByRole('button', { name: 'Add plain partition' }).click();
78+
await frame.getByRole('button', { name: '/home' }).click();
79+
await frame.getByRole('option', { name: '/tmp' }).click();
80+
81+
const removeRootButton = frame
82+
.getByRole('row')
83+
.nth(1)
84+
.getByRole('button')
85+
.nth(4);
86+
87+
await expect(removeRootButton).toBeDisabled();
88+
89+
await frame
90+
.getByRole('textbox', { name: 'mountpoint suffix' })
91+
.fill('/usb');
92+
93+
await frame.getByPlaceholder('Define minimum size').nth(1).fill('10');
94+
await frame.getByRole('button', { name: 'GiB' }).nth(1).click();
95+
await frame.getByRole('option', { name: 'KiB' }).click();
96+
97+
await expect(removeRootButton).toBeDisabled();
98+
99+
await frame.getByRole('button', { name: 'Add LVM volume group' }).click();
100+
101+
await frame
102+
.getByRole('textbox', { name: 'Volume group name input' })
103+
.fill('vg-name');
104+
await frame
105+
.getByRole('textbox', { name: 'minimum partition size' })
106+
.nth(1)
107+
.fill('10');
108+
await frame.getByRole('button', { name: 'GiB' }).nth(1).click();
109+
await frame.getByRole('option', { name: 'KiB' }).click();
110+
111+
await frame
112+
.getByRole('textbox', { name: 'Partition name input' })
113+
.fill('lv1');
114+
await frame.getByRole('button', { name: 'Add logical volume' }).click();
115+
await frame.getByRole('button', { name: '/home' }).nth(1).click();
116+
await frame.getByRole('option', { name: '/tmp' }).click();
117+
118+
await frame
119+
.getByRole('row', {
120+
name: 'Draggable row draggable button /tmp ext4 1 GiB',
121+
})
122+
.getByLabel('Partition name input')
123+
.fill('lv2');
124+
await frame
125+
.getByRole('row', {
126+
name: 'Draggable row draggable button lv2 /tmp ext4 1 GiB',
127+
})
128+
.getByLabel('mountpoint suffix')
129+
.fill('/usb');
130+
await frame
131+
.getByRole('row', {
132+
name: 'Draggable row draggable button lv2 /tmp /usb ext4 1 GiB',
133+
})
134+
.getByPlaceholder('Define minimum size')
135+
.fill('10');
136+
await frame.getByRole('button', { name: 'GiB' }).nth(2).click();
137+
await frame.getByRole('option', { name: 'KiB' }).click();
138+
});
139+
140+
await test.step('Fill the BP details', async () => {
141+
await frame.getByRole('button', { name: 'Review and finish' }).click();
142+
await fillInDetails(frame, blueprintName);
143+
});
144+
145+
await test.step('Create BP', async () => {
146+
await createBlueprint(frame, blueprintName);
147+
});
148+
149+
await test.step('Edit BP', async () => {
150+
await frame.getByRole('button', { name: 'Edit blueprint' }).click();
151+
await frame.getByLabel('Revisit File system configuration step').click();
152+
153+
const removeRootButton = frame
154+
.getByRole('row')
155+
.nth(1)
156+
.getByRole('button')
157+
.nth(4);
158+
await expect(removeRootButton).toBeDisabled();
159+
160+
const secondRow = frame.getByRole('row').nth(2);
161+
162+
const removeTmpButton = secondRow.getByRole('button').nth(4);
163+
await expect(removeTmpButton).toBeEnabled();
164+
165+
await expect(
166+
secondRow.getByRole('textbox', { name: 'mountpoint suffix' }),
167+
).toHaveValue('/usb');
168+
169+
await secondRow
170+
.getByRole('gridcell', { name: '10', exact: true })
171+
.getByPlaceholder('Define minimum size')
172+
.click();
173+
await secondRow
174+
.getByRole('gridcell', { name: '10', exact: true })
175+
.getByPlaceholder('Define minimum size')
176+
.fill('5');
177+
178+
await secondRow.getByRole('button', { name: '/tmp' }).click();
179+
await expect(
180+
secondRow.getByRole('textbox', { name: 'mountpoint suffix' }),
181+
).toBeVisible();
182+
await frame.getByRole('option', { name: '/usr' }).click();
183+
await expect(
184+
secondRow.getByRole('textbox', { name: 'mountpoint suffix' }),
185+
).toBeHidden();
186+
187+
await secondRow.getByRole('button', { name: '/usr' }).click();
188+
await frame.getByRole('option', { name: '/srv' }).click();
189+
190+
await secondRow
191+
.getByRole('textbox', { name: 'mountpoint suffix' })
192+
.fill('/data');
193+
194+
await secondRow.getByRole('button', { name: 'KiB' }).click();
195+
await frame.getByRole('option', { name: 'MiB' }).click();
196+
197+
await frame
198+
.getByRole('textbox', { name: 'Volume group name input' })
199+
.fill('vg-edited-name');
200+
await frame
201+
.getByRole('textbox', { name: 'Partition name input' })
202+
.nth(1)
203+
.fill('lv1-edited');
204+
205+
await frame.getByRole('button', { name: 'ext4' }).nth(1).click();
206+
await frame.getByRole('option', { name: 'xfs' }).click();
207+
208+
await frame.getByRole('button', { name: 'Review and finish' }).click();
209+
await frame
210+
.getByRole('button', { name: 'Save changes to blueprint' })
211+
.click();
212+
});
213+
214+
let exportedBP = '';
215+
await test.step('Export BP', async () => {
216+
exportedBP = await exportBlueprint(page);
217+
await cleanup.add(async () => {
218+
await fsPromises.rm(path.dirname(exportedBP), { recursive: true });
219+
});
220+
});
221+
222+
// Temporarily commenting this out, needs to be addressed in a follow up
223+
// await test.step('Review exported BP', async (step) => {
224+
// step.skip(
225+
// isHosted(),
226+
// 'Only verify the contents of the exported blueprint in cockpit',
227+
// );
228+
// await verifyExportedBlueprint(exportedBP, exportedDiskBP(blueprintName));
229+
// });
230+
231+
await test.step('Import BP', async (step) => {
232+
step.skip(!isHosted(), 'Importing is not available in the plugin');
233+
await importBlueprint(page, exportedBP);
234+
});
235+
236+
await test.step('Review imported BP', async (step) => {
237+
step.skip(!isHosted(), 'Importing is not available in the plugin');
238+
await fillInImageOutputGuest(page);
239+
await frame
240+
.getByRole('button', { name: 'File system configuration' })
241+
.click();
242+
243+
const removeRootButton = frame
244+
.getByRole('row')
245+
.nth(1)
246+
.getByRole('button')
247+
.nth(4);
248+
249+
await expect(removeRootButton).toBeDisabled();
250+
251+
const secondRow = frame.getByRole('row').nth(2);
252+
253+
const removeTmpButton = secondRow.getByRole('button').nth(4);
254+
await expect(removeTmpButton).toBeEnabled();
255+
256+
const dataTextbox = secondRow.getByRole('textbox', {
257+
name: 'mountpoint suffix',
258+
});
259+
await expect(dataTextbox).toHaveValue('/data');
260+
261+
const size = secondRow.getByPlaceholder('Define minimum size');
262+
await expect(size).toHaveValue('5');
263+
264+
const typeButton = secondRow.getByRole('button', { name: 'xfs' });
265+
await expect(typeButton).toBeVisible();
266+
267+
const unitButton = secondRow.getByRole('button', { name: 'MiB' });
268+
await expect(unitButton).toBeVisible();
269+
270+
await page.getByRole('button', { name: 'Cancel' }).click();
271+
});
272+
});

playwright/fixtures/data/exportBlueprintContents.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
export const exportedDiskBP = (blueprintName: string): string => {
2+
return `name = "${blueprintName}"
3+
4+
[customizations]
5+
[[customizations.disk.partitions]]
6+
type = "plain"
7+
mountpoint = "/data"
8+
fs_type = "ext4"
9+
minsize = "50 GiB"
10+
11+
[[customizations.disk.partitions]]
12+
type = "lvm"
13+
name = "mainvg"
14+
minsize = "20 GiB"
15+
16+
[[customizations.disk.partitions.logical_volumes]]
17+
name = "rootlv"
18+
mountpoint = "/"
19+
fs_type = "ext4"
20+
minsize = "2 GiB"
21+
22+
[customizations.timezone]
23+
timezone = "Etc/UTC"
24+
25+
[customizations.locale]
26+
languages = [ "C.UTF-8" ]`;
27+
};
28+
129
export const exportedFilesystemBP = (blueprintName: string): string => {
230
return `name = "${blueprintName}"
331

0 commit comments

Comments
 (0)