Skip to content

Commit 645f5b9

Browse files
committed
Updated tests
1 parent e538325 commit 645f5b9

File tree

3 files changed

+147
-74
lines changed

3 files changed

+147
-74
lines changed

tests/create_project.spec.js

Lines changed: 127 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,79 +4,140 @@ test('Create and delete a project', async ({ page }) => {
44
await page.goto('/projects');
55
await waitPageLoading(page);
66

7-
// Create a new project with a random name
87
const randomProjectName = Math.random().toString(36).substring(7);
9-
const projectNameInput = page.locator('[name="projectName"]');
10-
await projectNameInput.fill(randomProjectName);
11-
await projectNameInput.blur();
12-
const createProjectBtn = page.getByRole('button', { name: 'Create new project' });
13-
await createProjectBtn.waitFor();
14-
await createProjectBtn.click();
15-
16-
// Verify that the user is redirected to the project page
17-
await page.waitForURL(/\/projects\/\d+/);
18-
await expect(page.locator('h1:not(.modal-title)')).toHaveText(
19-
new RegExp('Project ' + randomProjectName + ' #\\d+')
20-
);
21-
22-
// Go back to projects list
23-
await page.goto('/projects');
24-
await waitPageLoading(page);
25-
await expect(page.getByRole('cell', { name: randomProjectName })).toHaveCount(1);
268

27-
// Get project row
9+
await test.step('Create a new project', async () => {
10+
await page.getByRole('button', { name: 'Create new project' }).click();
11+
12+
// Wait modal opening
13+
let modalTitle = page.locator('.modal.show .modal-title');
14+
await modalTitle.waitFor();
15+
await expect(modalTitle).toHaveText('Create new project');
16+
17+
// Fill form and submit
18+
const projectNameInput = page.getByLabel('Project name');
19+
await projectNameInput.fill(randomProjectName);
20+
const createProjectBtn = page.locator('.modal.show').getByRole('button', { name: 'Confirm' });
21+
await createProjectBtn.click();
22+
23+
// Verify that the user is redirected to the project page
24+
await page.waitForURL(/\/projects\/\d+/);
25+
await expect(page.locator('h1:not(.modal-title)')).toHaveText(
26+
new RegExp('Project ' + randomProjectName + ' #\\d+')
27+
);
28+
});
29+
30+
await test.step('Verify that new project is visible in projects page', async () => {
31+
// Go back to projects list
32+
await page.goto('/projects');
33+
await waitPageLoading(page);
34+
await expect(page.getByRole('cell', { name: randomProjectName })).toHaveCount(1);
35+
36+
const projectRow = await getProjectRow(page, randomProjectName);
37+
38+
// Open project info modal
39+
const infoBtn = /** @type {import('@playwright/test').Locator} */ (projectRow).getByRole(
40+
'button',
41+
{ name: 'Info' }
42+
);
43+
await infoBtn.click();
44+
45+
// Wait info modal
46+
let modalTitle = page.locator('.modal.show .modal-title');
47+
await modalTitle.waitFor();
48+
await expect(modalTitle).toHaveText('Project ' + randomProjectName);
49+
const items = await page.locator('.modal.show .modal-body').getByRole('listitem').all();
50+
expect(items.length).toEqual(4);
51+
expect(await items[1].innerText()).toEqual(randomProjectName);
52+
expect(await items[3].innerText()).toEqual('No');
53+
54+
let closeModalBtn = page.locator('.modal.show').getByRole('button', { name: 'Close' });
55+
await closeModalBtn.click();
56+
});
57+
58+
await test.step('Search the project', async () => {
59+
await page.getByPlaceholder('Search').fill(randomProjectName);
60+
expect(await page.getByRole('row').count()).toEqual(2);
61+
62+
await page.getByPlaceholder('Search').fill(`${randomProjectName}-foo`);
63+
expect(await page.getByRole('row').count()).toEqual(1);
64+
65+
await page.getByPlaceholder('Search').fill('');
66+
});
67+
68+
await test.step('Attempt to create a project with the same name', async () => {
69+
await page.getByRole('button', { name: 'Create new project' }).click();
70+
71+
// Wait modal opening
72+
let modalTitle = page.locator('.modal.show .modal-title');
73+
await modalTitle.waitFor();
74+
await expect(modalTitle).toHaveText('Create new project');
75+
76+
// Fill form and submit
77+
const projectNameInput = page.getByLabel('Project name');
78+
await projectNameInput.fill(randomProjectName);
79+
const createProjectBtn = page.locator('.modal.show').getByRole('button', { name: 'Confirm' });
80+
await createProjectBtn.click();
81+
82+
// Check validation error
83+
await page.waitForFunction((projectName) => {
84+
const invalidFeeback = document.querySelector('.modal.show .invalid-feedback');
85+
if (invalidFeeback instanceof HTMLElement) {
86+
return invalidFeeback.innerText.includes(`Project name (${projectName}) already in use`);
87+
}
88+
return false;
89+
}, randomProjectName);
90+
91+
// Close modal
92+
const closeModalBtn = page.locator('.modal.show').getByRole('button', { name: 'Cancel' });
93+
await closeModalBtn.click();
94+
});
95+
96+
await test.step('Delete project', async () => {
97+
const projectRow = await getProjectRow(page, randomProjectName);
98+
99+
// Click on the delete project button related to the current project
100+
const deleteBtn = /** @type {import('@playwright/test').Locator} */ (projectRow).getByRole(
101+
'button',
102+
{ name: 'Delete' }
103+
);
104+
await deleteBtn.click();
105+
106+
// Wait confirm action modal
107+
let modalTitle = page.locator('.modal.show .modal-title');
108+
await modalTitle.waitFor();
109+
await expect(modalTitle).toHaveText('Confirm action');
110+
await expect(page.locator('.modal.show .modal-body')).toContainText(
111+
'Delete project ' + randomProjectName
112+
);
113+
114+
// Confirm the deletion of the project
115+
await page.getByRole('button', { name: 'Confirm' }).click();
116+
117+
await page.waitForFunction((projectName) => {
118+
const projectNames = [...document.querySelectorAll('table td:nth-child(2)')].map(
119+
(c) => /** @type {HTMLElement} */ (c).innerText
120+
);
121+
return !projectNames.includes(projectName);
122+
}, randomProjectName);
123+
await expect(page.getByRole('cell', { name: randomProjectName })).toHaveCount(0);
124+
});
125+
});
126+
127+
/**
128+
* @param {import('@playwright/test').Page} page
129+
* @param {string} projectName
130+
* @returns {Promise<import('@playwright/test').Locator>}
131+
*/
132+
async function getProjectRow(page, projectName) {
28133
const rows = await page.getByRole('row').all();
29134
let projectRow;
30135
for (const row of rows) {
31-
if ((await row.getByRole('cell', { name: randomProjectName }).count()) === 1) {
136+
if ((await row.getByRole('cell', { name: projectName }).count()) === 1) {
32137
projectRow = row;
33138
break;
34139
}
35140
}
36141
expect(projectRow).toBeDefined();
37-
38-
// Open project info modal
39-
const infoBtn = /** @type {import('@playwright/test').Locator} */ (projectRow).getByRole(
40-
'button',
41-
{ name: 'Info' }
42-
);
43-
await infoBtn.click();
44-
45-
// Wait info modal
46-
let modalTitle = page.locator('.modal.show .modal-title');
47-
await modalTitle.waitFor();
48-
await expect(modalTitle).toHaveText('Project ' + randomProjectName);
49-
const items = await page.locator('.modal.show .modal-body').getByRole('listitem').all();
50-
expect(items.length).toEqual(4);
51-
expect(await items[1].innerText()).toEqual(randomProjectName);
52-
expect(await items[3].innerText()).toEqual('No');
53-
54-
let closeModalBtn = page.locator('.modal.show').getByRole('button', {name: 'Close'});
55-
await closeModalBtn.click();
56-
57-
// Click on the delete project button related to the current project
58-
const deleteBtn = /** @type {import('@playwright/test').Locator} */ (projectRow).getByRole(
59-
'button',
60-
{ name: 'Delete' }
61-
);
62-
await deleteBtn.click();
63-
64-
// Wait confirm action modal
65-
modalTitle = page.locator('.modal.show .modal-title');
66-
await modalTitle.waitFor();
67-
await expect(modalTitle).toHaveText('Confirm action');
68-
await expect(page.locator('.modal.show .modal-body')).toContainText(
69-
'Delete project ' + randomProjectName
70-
);
71-
72-
// Confirm the deletion of the project
73-
await page.getByRole('button', { name: 'Confirm' }).click();
74-
75-
await page.waitForFunction((projectName) => {
76-
const projectNames = [...document.querySelectorAll('table td:nth-child(2)')].map(
77-
(c) => /** @type {HTMLElement} */ (c).innerText
78-
);
79-
return !projectNames.includes(projectName);
80-
}, randomProjectName);
81-
await expect(page.getByRole('cell', { name: randomProjectName })).toHaveCount(0);
82-
});
142+
return /** @type {import('@playwright/test').Locator} */ (projectRow);
143+
}

tests/login_logout.spec.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ test.describe(() => {
5555
await page.goto('/auth/login');
5656
await login(page);
5757
await page.context().clearCookies();
58-
const projectNameInput = page.locator('[name="projectName"]');
58+
await page.getByRole('button', { name: 'Create new project' }).click();
59+
let modalTitle = page.locator('.modal.show .modal-title');
60+
await modalTitle.waitFor();
61+
const projectNameInput = page.getByLabel('Project name');
5962
await projectNameInput.fill('unauthorized');
60-
await projectNameInput.blur();
61-
const createProjectBtn = page.getByRole('button', { name: 'Create new project' });
62-
await createProjectBtn.waitFor();
63+
const createProjectBtn = page.locator('.modal.show').getByRole('button', { name: 'Confirm' });
6364
await createProjectBtn.click();
6465
await page.waitForURL('/auth/login?invalidate=true');
6566
await verifySessionExpiredMessage(page);

tests/project_fixture.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,23 @@ export class PageWithProject {
1313
async createProject() {
1414
await this.page.goto('/projects');
1515
await waitPageLoading(this.page);
16-
const projectNameInput = this.page.locator('[name="projectName"]');
16+
17+
await this.page.getByRole('button', { name: 'Create new project' }).click();
18+
19+
// Wait modal opening
20+
let modalTitle = this.page.locator('.modal.show .modal-title');
21+
await modalTitle.waitFor();
22+
await expect(modalTitle).toHaveText('Create new project');
23+
24+
// Fill form and submit
25+
const projectNameInput = this.page.getByLabel('Project name');
1726
await projectNameInput.fill(this.projectName);
18-
await projectNameInput.blur();
19-
const createProjectBtn = this.page.getByRole('button', { name: 'Create new project' });
20-
await createProjectBtn.waitFor();
27+
const createProjectBtn = this.page
28+
.locator('.modal.show')
29+
.getByRole('button', { name: 'Confirm' });
2130
await createProjectBtn.click();
31+
32+
// Verify that the user is redirected to the project page
2233
await this.page.waitForURL(/\/projects\/\d+/);
2334
this.url = this.page.url();
2435
const match = this.url.match(/\/projects\/(\d+)/);

0 commit comments

Comments
 (0)