🐛(frontend) improve e2e tests avoiding race condition from mocks
Reorder mock setup with page.route so that it takes place before nav.
This commit is contained in:
committed by
Laurent Bossavit
parent
8a2b0d0a76
commit
e7af1fd591
@@ -46,6 +46,7 @@ and this project adheres to
|
||||
|
||||
### Fixed
|
||||
|
||||
- 🐛(frontend) improve e2e tests avoiding race condition from mocks #641
|
||||
- 🐛(backend) fix flaky test with search contact #605
|
||||
- 🐛(backend) fix flaky test with team access #646
|
||||
- 🧑💻(dimail) remove 'NoneType: None' log in debug mode
|
||||
|
||||
2
src/frontend/apps/desk/next-env.d.ts
vendored
2
src/frontend/apps/desk/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
|
||||
|
||||
@@ -60,12 +60,6 @@ test.describe('Config', () => {
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await page.goto('/');
|
||||
// Login with a user who has the visibility on the groups should see groups
|
||||
// It's now the backend that decides if the user can see the group menu and they
|
||||
// should be redirected to the groups page in such case
|
||||
await keyCloakSignIn(page, browserName, 'team-administrator');
|
||||
|
||||
await page.route('**/api/v1.0/config/', async (route) => {
|
||||
const request = route.request();
|
||||
if (request.method().includes('GET')) {
|
||||
@@ -83,6 +77,12 @@ test.describe('Config', () => {
|
||||
}
|
||||
});
|
||||
|
||||
await page.goto('/');
|
||||
// Login with a user who has the visibility on the groups should see groups
|
||||
// It's now the backend that decides if the user can see the group menu and they
|
||||
// should be redirected to the groups page in such case
|
||||
await keyCloakSignIn(page, browserName, 'team-administrator');
|
||||
|
||||
await expect(page.locator('menu')).toBeHidden();
|
||||
|
||||
await expect(page.getByText('Groups')).toBeVisible();
|
||||
|
||||
@@ -25,9 +25,9 @@ const payloadGetTeams = {
|
||||
],
|
||||
};
|
||||
|
||||
const mockApiRequests = (page: Page) => {
|
||||
void page.route('**/teams/?ordering=-created_at', (route) => {
|
||||
void route.fulfill({
|
||||
const mockApiRequests = async (page: Page) => {
|
||||
await page.route('**/teams/?ordering=-created_at', async (route) => {
|
||||
await route.fulfill({
|
||||
json: payloadGetTeams.results,
|
||||
});
|
||||
});
|
||||
@@ -40,11 +40,11 @@ test.describe('Keyboard navigation', () => {
|
||||
}) => {
|
||||
const page = await browser.newPage();
|
||||
|
||||
await mockApiRequests(page);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'team-owner-mail-member');
|
||||
|
||||
void mockApiRequests(page);
|
||||
|
||||
const header = page.locator('header');
|
||||
|
||||
// La Gauffre button is loaded asynchronously, so we wait for it to be visible
|
||||
|
||||
@@ -85,10 +85,13 @@ const mailboxesFixtures = {
|
||||
},
|
||||
};
|
||||
|
||||
const interceptCommonApiRequests = (page: Page, mailDomains?: MailDomain[]) => {
|
||||
const interceptCommonApiRequests = async (
|
||||
page: Page,
|
||||
mailDomains?: MailDomain[],
|
||||
) => {
|
||||
const mailDomainsToUse = mailDomains ?? mailDomainsFixtures;
|
||||
void page.route('**/api/v1.0/mail-domains/?page=*', (route) => {
|
||||
void route.fulfill({
|
||||
await page.route('**/api/v1.0/mail-domains/?page=*', async (route) => {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
count: mailDomainsToUse.length,
|
||||
next: null,
|
||||
@@ -98,28 +101,37 @@ const interceptCommonApiRequests = (page: Page, mailDomains?: MailDomain[]) => {
|
||||
});
|
||||
});
|
||||
|
||||
mailDomainsToUse.forEach((mailDomain) => {
|
||||
void page.route(`**/api/v1.0/mail-domains/${mailDomain.slug}/`, (route) => {
|
||||
void route.fulfill({
|
||||
json: mailDomain,
|
||||
});
|
||||
});
|
||||
await Promise.all(
|
||||
mailDomainsToUse.map(async (mailDomain) => {
|
||||
await page.route(
|
||||
`**/api/v1.0/mail-domains/${mailDomain.slug}/`,
|
||||
async (route) => {
|
||||
await route.fulfill({
|
||||
json: mailDomain,
|
||||
});
|
||||
},
|
||||
);
|
||||
}),
|
||||
);
|
||||
|
||||
void page.route(
|
||||
`**/api/v1.0/mail-domains/${mailDomain.slug}/mailboxes/?page=1**`,
|
||||
(route) => {
|
||||
void route.fulfill({
|
||||
json: {
|
||||
count: mailboxesFixtures.domainFr.page1.length,
|
||||
next: null,
|
||||
previous: null,
|
||||
results: mailboxesFixtures.domainFr.page1,
|
||||
},
|
||||
});
|
||||
},
|
||||
{ times: 1 },
|
||||
);
|
||||
});
|
||||
await Promise.all(
|
||||
mailDomainsToUse.map(async (mailDomain) => {
|
||||
await page.route(
|
||||
`**/api/v1.0/mail-domains/${mailDomain.slug}/mailboxes/?page=1**`,
|
||||
async (route) => {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
count: mailboxesFixtures.domainFr.page1.length,
|
||||
next: null,
|
||||
previous: null,
|
||||
results: mailboxesFixtures.domainFr.page1,
|
||||
},
|
||||
});
|
||||
},
|
||||
{ times: 1 },
|
||||
);
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const navigateToMailboxCreationFormForMailDomainFr = async (
|
||||
@@ -131,19 +143,20 @@ const navigateToMailboxCreationFormForMailDomainFr = async (
|
||||
};
|
||||
|
||||
test.describe('Mail domain create mailbox', () => {
|
||||
test.beforeEach(async ({ page, browserName }) => {
|
||||
await page.goto('/');
|
||||
// Login with a user who has the visibility on the mail domains
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
});
|
||||
|
||||
test('checks create mailbox button is visible or not', async ({ page }) => {
|
||||
test('checks create mailbox button is visible or not', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
const domains = [...mailDomainsFixtures];
|
||||
domains[0].status = 'enabled';
|
||||
domains[1].status = 'pending';
|
||||
domains[2].status = 'disabled';
|
||||
domains[3].status = 'failed';
|
||||
void interceptCommonApiRequests(page, domains);
|
||||
await interceptCommonApiRequests(page, domains);
|
||||
|
||||
await page.goto('/');
|
||||
// Login with a user who has the visibility on the mail domains
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
|
||||
await page
|
||||
.locator('menu')
|
||||
@@ -190,6 +203,7 @@ test.describe('Mail domain create mailbox', () => {
|
||||
|
||||
test('checks user can create a mailbox when he has post ability', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
const newMailbox = {
|
||||
id: '04433733-c9b7-453a-8122-755ac115bb00',
|
||||
@@ -197,13 +211,13 @@ test.describe('Mail domain create mailbox', () => {
|
||||
secondary_email: 'john.doe-complex2024@mail.com',
|
||||
};
|
||||
|
||||
const interceptRequests = (page: Page) => {
|
||||
void interceptCommonApiRequests(page);
|
||||
const interceptRequests = async (page: Page) => {
|
||||
await interceptCommonApiRequests(page);
|
||||
|
||||
void page.route(
|
||||
await page.route(
|
||||
'**/api/v1.0/mail-domains/domainfr/mailboxes/?page=1**',
|
||||
(route) => {
|
||||
void route.fulfill({
|
||||
async (route) => {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
count: [...mailboxesFixtures.domainFr.page1, newMailbox].length,
|
||||
next: null,
|
||||
@@ -214,15 +228,15 @@ test.describe('Mail domain create mailbox', () => {
|
||||
},
|
||||
);
|
||||
|
||||
void page.route(
|
||||
await page.route(
|
||||
'**/api/v1.0/mail-domains/domainfr/mailboxes/',
|
||||
(route) => {
|
||||
async (route) => {
|
||||
if (route.request().method() === 'POST') {
|
||||
void route.fulfill({
|
||||
await route.fulfill({
|
||||
json: newMailbox,
|
||||
});
|
||||
} else {
|
||||
void route.continue();
|
||||
await route.continue();
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -249,8 +263,12 @@ test.describe('Mail domain create mailbox', () => {
|
||||
}
|
||||
});
|
||||
|
||||
void interceptRequests(page);
|
||||
expect(true).toBeTruthy();
|
||||
await interceptRequests(page);
|
||||
|
||||
await page.goto('/');
|
||||
// Login with a user who has the visibility on the mail domains
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
|
||||
await navigateToMailboxCreationFormForMailDomainFr(page);
|
||||
|
||||
await page.getByRole('button', { name: 'Cancel' }).click();
|
||||
@@ -315,15 +333,16 @@ test.describe('Mail domain create mailbox', () => {
|
||||
|
||||
test('checks user is not allowed to create a mailbox when he is missing post ability', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
const localMailDomainsFixtures = [...mailDomainsFixtures];
|
||||
localMailDomainsFixtures[0].abilities.post = false;
|
||||
const localMailDomainDomainFr = localMailDomainsFixtures[0];
|
||||
const localMailboxFixtures = { ...mailboxesFixtures };
|
||||
|
||||
const interceptRequests = (page: Page) => {
|
||||
void page.route('**/api/v1.0/mail-domains/?page=*', (route) => {
|
||||
void route.fulfill({
|
||||
const interceptRequests = async (page: Page) => {
|
||||
await page.route('**/api/v1.0/mail-domains/?page=*', async (route) => {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
count: localMailDomainsFixtures.length,
|
||||
next: null,
|
||||
@@ -333,16 +352,16 @@ test.describe('Mail domain create mailbox', () => {
|
||||
});
|
||||
});
|
||||
|
||||
void page.route('**/api/v1.0/mail-domains/domainfr/', (route) => {
|
||||
void route.fulfill({
|
||||
await page.route('**/api/v1.0/mail-domains/domainfr/', async (route) => {
|
||||
await route.fulfill({
|
||||
json: localMailDomainDomainFr,
|
||||
});
|
||||
});
|
||||
|
||||
void page.route(
|
||||
await page.route(
|
||||
'**/api/v1.0/mail-domains/domainfr/mailboxes/?page=1**',
|
||||
(route) => {
|
||||
void route.fulfill({
|
||||
async (route) => {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
count: localMailboxFixtures.domainFr.page1.length,
|
||||
next: null,
|
||||
@@ -355,7 +374,11 @@ test.describe('Mail domain create mailbox', () => {
|
||||
);
|
||||
};
|
||||
|
||||
void interceptRequests(page);
|
||||
await interceptRequests(page);
|
||||
|
||||
await page.goto('/');
|
||||
// Login with a user who has the visibility on the mail domains
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
|
||||
await page
|
||||
.locator('menu')
|
||||
|
||||
@@ -142,11 +142,6 @@ test.describe('Mail domain', () => {
|
||||
});
|
||||
|
||||
test.describe('user is administrator or owner', () => {
|
||||
test.beforeEach(async ({ page, browserName }) => {
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-owner');
|
||||
});
|
||||
|
||||
test.describe('mail domain is enabled', () => {
|
||||
const mailDomainsFixtures: MailDomain[] = [
|
||||
{
|
||||
@@ -215,9 +210,12 @@ test.describe('Mail domain', () => {
|
||||
},
|
||||
];
|
||||
|
||||
test('checks if all tabs are visible', async ({ page }) => {
|
||||
test('checks if all tabs are visible', async ({ page, browserName }) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-owner');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
@@ -230,9 +228,13 @@ test.describe('Mail domain', () => {
|
||||
|
||||
test('checks all the elements are visible when domain exist but contains no mailboxes', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-owner');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
@@ -248,6 +250,7 @@ test.describe('Mail domain', () => {
|
||||
|
||||
test('checks all the elements are visible when domain exists and contains 2 pages of mailboxes', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
const mailboxesFixtures = {
|
||||
domainFr: {
|
||||
@@ -324,6 +327,9 @@ test.describe('Mail domain', () => {
|
||||
|
||||
await interceptApiCalls();
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-owner');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
@@ -360,9 +366,15 @@ test.describe('Mail domain', () => {
|
||||
},
|
||||
];
|
||||
|
||||
test('checks expected elements are visible', async ({ page }) => {
|
||||
test('checks expected elements are visible', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-owner');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await expect(page).toHaveURL(/mail-domains\//);
|
||||
@@ -404,9 +416,15 @@ test.describe('Mail domain', () => {
|
||||
},
|
||||
];
|
||||
|
||||
test('checks expected elements are visible', async ({ page }) => {
|
||||
test('checks expected elements are visible', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-owner');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
@@ -447,9 +465,15 @@ test.describe('Mail domain', () => {
|
||||
},
|
||||
];
|
||||
|
||||
test('checks expected elements are visible', async ({ page }) => {
|
||||
test('checks expected elements are visible', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-owner');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
@@ -476,11 +500,6 @@ test.describe('Mail domain', () => {
|
||||
});
|
||||
|
||||
test.describe('user is member', () => {
|
||||
test.beforeEach(async ({ page, browserName }) => {
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
});
|
||||
|
||||
test.describe('mail domain is enabled', () => {
|
||||
const mailDomainsFixtures: MailDomain[] = [
|
||||
{
|
||||
@@ -551,9 +570,13 @@ test.describe('Mail domain', () => {
|
||||
|
||||
test('checks all the elements are visible when domain exist but contains no mailboxes', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
@@ -569,6 +592,7 @@ test.describe('Mail domain', () => {
|
||||
|
||||
test('checks all the elements are visible when domain exists and contains 2 pages of mailboxes', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
const mailboxesFixtures = {
|
||||
domainFr: {
|
||||
@@ -645,6 +669,9 @@ test.describe('Mail domain', () => {
|
||||
|
||||
await interceptApiCalls();
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
@@ -681,9 +708,15 @@ test.describe('Mail domain', () => {
|
||||
},
|
||||
];
|
||||
|
||||
test('checks expected elements are visible', async ({ page }) => {
|
||||
test('checks expected elements are visible', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await expect(page).toHaveURL(/mail-domains\//);
|
||||
@@ -725,9 +758,15 @@ test.describe('Mail domain', () => {
|
||||
},
|
||||
];
|
||||
|
||||
test('checks expected elements are visible', async ({ page }) => {
|
||||
test('checks expected elements are visible', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
@@ -768,9 +807,15 @@ test.describe('Mail domain', () => {
|
||||
},
|
||||
];
|
||||
|
||||
test('checks expected elements are visible', async ({ page }) => {
|
||||
test('checks expected elements are visible', async ({
|
||||
page,
|
||||
browserName,
|
||||
}) => {
|
||||
await interceptCommonApiCalls(page, mailDomainsFixtures);
|
||||
|
||||
await page.goto('/');
|
||||
await keyCloakSignIn(page, browserName, 'mail-member');
|
||||
|
||||
await clickOnMailDomainsNavButton(page);
|
||||
|
||||
await assertMailDomainUpperElementsAreVisible(page);
|
||||
|
||||
@@ -73,16 +73,14 @@ const mailDomainsFixtures: MailDomain[] = [
|
||||
|
||||
test.describe('Mail domains', () => {
|
||||
test.describe('checks all the elements are visible', () => {
|
||||
test.beforeEach(async ({ page, browserName }) => {
|
||||
test('checks the sort button', async ({ page, browserName }) => {
|
||||
await page.goto('/');
|
||||
// The user is a team administrator, so they land on the team page
|
||||
// This allows to prevent the redirection to the mail domains page
|
||||
// to make the '/api/v1.0/mail-domains/?page=1&ordering=created_at'
|
||||
// query at login, which will be cached and not called afterward in tests.
|
||||
await keyCloakSignIn(page, browserName, 'team-administrator-mail-member');
|
||||
});
|
||||
|
||||
test('checks the sort button', async ({ page }) => {
|
||||
await page
|
||||
.locator('menu')
|
||||
.first()
|
||||
@@ -128,7 +126,7 @@ test.describe('Mail domains', () => {
|
||||
expect(responseSortDesc.ok()).toBeTruthy();
|
||||
});
|
||||
|
||||
test('when no mail domain exists', async ({ page }) => {
|
||||
test('when no mail domain exists', async ({ page, browserName }) => {
|
||||
await page.route('**/api/v1.0/mail-domains/?page=*', async (route) => {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
@@ -140,6 +138,13 @@ test.describe('Mail domains', () => {
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto('/');
|
||||
// The user is a team administrator, so they land on the team page
|
||||
// This allows to prevent the redirection to the mail domains page
|
||||
// to make the '/api/v1.0/mail-domains/?page=1&ordering=created_at'
|
||||
// query at login, which will be cached and not called afterward in tests.
|
||||
await keyCloakSignIn(page, browserName, 'team-administrator-mail-member');
|
||||
|
||||
await page
|
||||
.locator('menu')
|
||||
.first()
|
||||
@@ -152,7 +157,7 @@ test.describe('Mail domains', () => {
|
||||
await expect(page.getByText('No domains exist.')).toBeVisible();
|
||||
});
|
||||
|
||||
test('when 4 mail domains exist', async ({ page }) => {
|
||||
test('when 4 mail domains exist', async ({ page, browserName }) => {
|
||||
await page.route('**/api/v1.0/mail-domains/?page=*', async (route) => {
|
||||
await route.fulfill({
|
||||
json: {
|
||||
@@ -164,6 +169,13 @@ test.describe('Mail domains', () => {
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto('/');
|
||||
// The user is a team administrator, so they land on the team page
|
||||
// This allows to prevent the redirection to the mail domains page
|
||||
// to make the '/api/v1.0/mail-domains/?page=1&ordering=created_at'
|
||||
// query at login, which will be cached and not called afterward in tests.
|
||||
await keyCloakSignIn(page, browserName, 'team-administrator-mail-member');
|
||||
|
||||
await page
|
||||
.locator('menu')
|
||||
.first()
|
||||
|
||||
@@ -9,7 +9,7 @@ const baseURL = `http://localhost:${PORT}`;
|
||||
*/
|
||||
export default defineConfig({
|
||||
// Timeout per test
|
||||
timeout: 30 * 1000,
|
||||
timeout: 10 * 1000,
|
||||
testDir: './__tests__',
|
||||
outputDir: './test-results',
|
||||
|
||||
|
||||
Reference in New Issue
Block a user