️(e2e) unique login between tests

We will cache the login token in the browser
storage and reuse it between tests.
This will speed up the tests and reduce the
load on the server.
This commit is contained in:
Anthony LC
2024-06-06 22:13:18 +02:00
committed by Anthony LC
parent b68015852c
commit 4e4e2e23e3
16 changed files with 149 additions and 53 deletions

View File

@@ -27,6 +27,7 @@ and this project adheres to
- 🔧 (helm) sticky session by request_uri for signaling server (#78) - 🔧 (helm) sticky session by request_uri for signaling server (#78)
- (frontend) change logo (#84) - (frontend) change logo (#84)
- (frontend) pdf has title doc (#84) - (frontend) pdf has title doc (#84)
- ⚡️(e2e) unique login between tests (#80)
## Fixed ## Fixed

View File

@@ -2,4 +2,5 @@
test-results/ test-results/
report/ report/
blob-report/ blob-report/
playwright/.auth/
playwright/.cache/ playwright/.cache/

View File

@@ -1,10 +1,10 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { keyCloakSignIn } from './common'; test.beforeEach(async ({ page }) => {
test.beforeEach(async ({ page, browserName }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName); await expect(
page.locator('header').first().locator('h2').getByText('Docs'),
).toBeVisible();
await page.goto('unknown-page404'); await page.goto('unknown-page404');
}); });

View File

@@ -0,0 +1,19 @@
import { test as setup } from '@playwright/test';
import { keyCloakSignIn } from './common';
setup('authenticate-chromium', async ({ page }) => {
await page.goto('/');
await keyCloakSignIn(page, 'chromium');
await page
.context()
.storageState({ path: `playwright/.auth/user-chromium.json` });
});
setup('authenticate-webkit', async ({ page }) => {
await page.goto('/');
await keyCloakSignIn(page, 'webkit');
await page
.context()
.storageState({ path: `playwright/.auth/user-webkit.json` });
});

View File

@@ -5,14 +5,17 @@ export const keyCloakSignIn = async (page: Page, browserName: string) => {
timeout: 5000, timeout: 5000,
}); });
if (title?.includes('Sign in to your account')) { const login = `user-e2e-${browserName}`;
await page const password = `password-e2e-${browserName}`;
.getByRole('textbox', { name: 'username' })
.fill(`user-e2e-${browserName}`);
await page if (await page.getByLabel('Restart login').isVisible()) {
.getByRole('textbox', { name: 'password' }) await page.getByRole('textbox', { name: 'password' }).fill(password);
.fill(`password-e2e-${browserName}`);
await page.click('input[type="submit"]', { force: true });
} else if (title?.includes('Sign in to your account')) {
await page.getByRole('textbox', { name: 'username' }).fill(login);
await page.getByRole('textbox', { name: 'password' }).fill(password);
await page.click('input[type="submit"]', { force: true }); await page.click('input[type="submit"]', { force: true });
} }

View File

@@ -1,10 +1,7 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { keyCloakSignIn } from './common'; test.beforeEach(async ({ page }) => {
test.beforeEach(async ({ page, browserName }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Footer', () => { test.describe('Footer', () => {

View File

@@ -2,9 +2,8 @@ import { expect, test } from '@playwright/test';
import { keyCloakSignIn } from './common'; import { keyCloakSignIn } from './common';
test.beforeEach(async ({ page, browserName }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Header', () => { test.describe('Header', () => {
@@ -64,8 +63,15 @@ test.describe('Header', () => {
await expect(page.getByRole('link', { name: 'Grist' })).toBeVisible(); await expect(page.getByRole('link', { name: 'Grist' })).toBeVisible();
}); });
});
test.describe('Header: Log out', () => {
test.use({ storageState: { cookies: [], origins: [] } });
test('checks logout button', async ({ page, browserName }) => {
await page.goto('/');
await keyCloakSignIn(page, browserName);
test('checks logout button', async ({ page }) => {
await page await page
.getByRole('button', { .getByRole('button', {
name: 'My account', name: 'My account',

View File

@@ -1,10 +1,7 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { keyCloakSignIn } from './common'; test.beforeEach(async ({ page }) => {
test.beforeEach(async ({ page, browserName }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Language', () => { test.describe('Language', () => {

View File

@@ -1,10 +1,9 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { createPad, keyCloakSignIn, randomName } from './common'; import { createPad, randomName } from './common';
test.beforeEach(async ({ page, browserName }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Document add users', () => { test.describe('Document add users', () => {

View File

@@ -1,10 +1,7 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { keyCloakSignIn } from './common'; test.beforeEach(async ({ page }) => {
test.beforeEach(async ({ page, browserName }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Pad Create', () => { test.describe('Pad Create', () => {

View File

@@ -1,10 +1,9 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { createPad, keyCloakSignIn } from './common'; import { createPad } from './common';
test.beforeEach(async ({ page, browserName }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Pad Editor', () => { test.describe('Pad Editor', () => {

View File

@@ -1,10 +1,9 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { addNewMember, createPad, keyCloakSignIn } from './common'; import { addNewMember, createPad } from './common';
test.beforeEach(async ({ page, browserName }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Members Delete', () => { test.describe('Members Delete', () => {

View File

@@ -1,10 +1,9 @@
import { expect, test } from '@playwright/test'; import { expect, test } from '@playwright/test';
import { createPad, keyCloakSignIn } from './common'; import { createPad } from './common';
test.beforeEach(async ({ page, browserName }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Document grid members', () => { test.describe('Document grid members', () => {

View File

@@ -2,11 +2,10 @@ import { expect, test } from '@playwright/test';
import { waitForElementCount } from '../helpers'; import { waitForElementCount } from '../helpers';
import { createPad, keyCloakSignIn } from './common'; import { createPad } from './common';
test.beforeEach(async ({ page, browserName }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Documents Panel', () => { test.describe('Documents Panel', () => {
@@ -62,17 +61,87 @@ test.describe('Documents Panel', () => {
expect(responseSortDesc.ok()).toBeTruthy(); expect(responseSortDesc.ok()).toBeTruthy();
}); });
test('checks the infinite scroll', async ({ page, browserName }) => { test('checks the infinite scroll', async ({ page }) => {
test.setTimeout(90000); await page.route(
/.*\/documents\/\?page=.*&ordering=-created_at/,
async (route) => {
const request = route.request();
const url = new URL(request.url());
const pageId = url.searchParams.get('page');
const documents = {
count: 40,
next: 'http://localhost:3000/documents/?page=2&ordering=-created_at',
previous: null,
results: Array.from({ length: 20 }, (_, i) => ({
id: `2ff-${pageId}-${i}`,
title: `My document-${pageId}-${i}`,
accesses: [
{
id: 'b644e9b1-0517-4cfb-90ca-f7d6f2f6bb9a',
role: `owner`,
team: '',
user: {
id: 'a4743608-c9d8-4692-bef4-f795e25a3a88',
email: 'user@chromium.e2e',
},
},
],
content: '',
is_public: true,
abilities: {},
})),
};
if (request.method().includes('GET')) {
await route.fulfill({
json: documents,
});
} else {
await route.continue();
}
},
);
await page.route(`**/documents/2ff-1-16/`, async (route) => {
const request = route.request();
if (request.method().includes('GET')) {
await route.fulfill({
json: {
id: '2ff-1-16',
title: 'My document-1-16',
content: '',
abilities: {
partial_update: true,
},
accesses: [
{
id: 'b644e9b1-0517-4cfb-90ca-f7d6f2f6bb9a',
role: `owner`,
team: '',
user: {
id: 'a4743608-c9d8-4692-bef4-f795e25a3a88',
email: '',
},
},
],
},
});
} else {
await route.continue();
}
});
await page.goto('/');
const panel = page.getByLabel('Documents panel').first(); const panel = page.getByLabel('Documents panel').first();
const randomPads = await createPad(page, 'pad-infinite', browserName, 40);
await expect(panel.locator('li')).toHaveCount(20); await expect(panel.locator('li')).toHaveCount(20);
await panel.getByText(randomPads[24]).click(); await panel.getByText(`My document-1-16`).click();
await waitForElementCount(panel.locator('li'), 21, 10000); await waitForElementCount(panel.locator('li'), 21, 10000);
expect(await panel.locator('li').count()).toBeGreaterThan(20); expect(await panel.locator('li').count()).toBeGreaterThan(20);
await expect(panel.getByText(`My document-1-16`)).toBeVisible();
await expect(panel.getByText(`My document-2-15`)).toBeVisible();
}); });
test('checks the hover and selected state', async ({ page, browserName }) => { test('checks the hover and selected state', async ({ page, browserName }) => {

View File

@@ -2,11 +2,10 @@ import { expect, test } from '@playwright/test';
import cs from 'convert-stream'; import cs from 'convert-stream';
import pdf from 'pdf-parse'; import pdf from 'pdf-parse';
import { createPad, keyCloakSignIn } from './common'; import { createPad } from './common';
test.beforeEach(async ({ page, browserName }) => { test.beforeEach(async ({ page }) => {
await page.goto('/'); await page.goto('/');
await keyCloakSignIn(page, browserName);
}); });
test.describe('Pad Tools', () => { test.describe('Pad Tools', () => {

View File

@@ -25,7 +25,7 @@ export default defineConfig({
reporter: [['html', { outputFolder: './report' }]], reporter: [['html', { outputFolder: './report' }]],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: { use: {
baseURL: baseURL, baseURL,
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry', trace: 'on-first-retry',
@@ -42,13 +42,24 @@ export default defineConfig({
/* Configure projects for major browsers */ /* Configure projects for major browsers */
projects: [ projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
{ {
name: 'chromium', name: 'chromium',
use: { ...devices['Desktop Chrome'], locale: 'en-US' }, use: {
...devices['Desktop Chrome'],
locale: 'en-US',
storageState: 'playwright/.auth/user-chromium.json',
},
dependencies: ['setup'],
}, },
{ {
name: 'webkit', name: 'webkit',
use: { ...devices['Desktop Safari'], locale: 'en-US' }, use: {
...devices['Desktop Safari'],
locale: 'en-US',
storageState: 'playwright/.auth/user-webkit.json',
},
dependencies: ['setup'],
}, },
], ],
}); });