E2E/Playwright: Upgrade playwright/dependencies and test server config (#26464)

* chore: upgrade playwright and test server config

* add post install script

* update config types

* fix visual test
This commit is contained in:
Saturnino Abril 2024-03-19 08:09:25 +08:00 committed by GitHub
parent 297135c5b4
commit 53471c7e8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 705 additions and 502 deletions

View File

@ -222,7 +222,7 @@ $(if mme2e_is_token_in_list "webhook-interactions" "$ENABLED_DOCKER_SERVICES"; t
$(if mme2e_is_token_in_list "playwright" "$ENABLED_DOCKER_SERVICES"; then
echo '
playwright:
image: mcr.microsoft.com/playwright:v1.38.1-jammy
image: mcr.microsoft.com/playwright:v1.42.1-jammy
entrypoint: ["/bin/bash", "-c"]
command: ["until [ -f /var/run/mm_terminate ]; do sleep 5; done"]
env_file:

View File

@ -14,7 +14,20 @@ EOF
# Install Playwright dependencies
mme2e_log "Prepare Playwright: install dependencies"
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- playwright bash -c "cd e2e-tests/playwright && rm -rf node_modules && npm install --cache /tmp/empty-cache"
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- playwright bash -c "cd e2e-tests/playwright && rm -rf node_modules && PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --cache /tmp/empty-cache"
mme2e_log "Prepare Playwright: environment info"
${MME2E_DC_SERVER} exec -T -u "$MME2E_UID" -- playwright bash <<"EOF"
cat <<INNEREOF
debian = $(cat /etc/debian_version)
uname = $(uname -m)
node = $(node -v)
npm = $(npm -v)
playwright = $(cd e2e-tests/playwright && npx playwright --version)
browsers
$(du -hs ~/ms-playwright/* | awk '{print " = " $2 " (" $1 ")"}')
INNEREOF
EOF
# Enable next line to debug Playwright
# export DEBUG=pw:protocol,pw:browser,pw:api

View File

@ -45,7 +45,7 @@ npm run test
Change to root directory, run docker container
```
docker run -it --rm -v "$(pwd):/mattermost/" --ipc=host mcr.microsoft.com/playwright:v1.41.1-jammy /bin/bash
docker run -it --rm -v "$(pwd):/mattermost/" --ipc=host mcr.microsoft.com/playwright:v1.42.1-jammy /bin/bash
```
#### 2. Inside the docker container
@ -57,7 +57,7 @@ export PW_HEADLESS=true
cd mattermost/e2e-tests/playwright
# Install npm packages. Use "npm ci" to match the automated environment
npm ci
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm ci
# Run specific test. See https://playwright.dev/docs/test-cli.
npm run test -- login --project=chrome

View File

@ -13,10 +13,11 @@ import testConfig from './test.config';
async function globalSetup() {
let adminClient: Client;
let adminUser: UserProfile | null;
({adminClient, adminUser} = await getAdminClient());
({adminClient, adminUser} = await getAdminClient({skipLog: true}));
if (!adminUser) {
const {client: firstClient} = await makeClient();
const firstClient = new Client();
firstClient.setUrl(testConfig.baseURL);
const defaultAdmin = getDefaultAdminUser();
await firstClient.createUser(defaultAdmin, '', '');
@ -100,8 +101,6 @@ async function printClientInfo(client: Client) {
- BuildHash = ${config.BuildHash}
- BuildHashEnterprise = ${config.BuildHashEnterprise}
- BuildEnterpriseReady = ${config.BuildEnterpriseReady}
- FeatureFlagAppsEnabled = ${config.FeatureFlagAppsEnabled}
- FeatureFlagCallsEnabled = ${config.FeatureFlagCallsEnabled}
- TelemetryId = ${config.TelemetryId}
- ServiceEnvironment = ${config.ServiceEnvironment}`);
}

File diff suppressed because it is too large Load Diff

View File

@ -12,29 +12,29 @@
"playwright-ui": "cross-env NODE_OPTIONS='--no-experimental-fetch' playwright test --ui",
"test-slomo": "cross-env NODE_OPTIONS='--no-experimental-fetch' PW_SNAPSHOT_ENABLE=true PW_SLOWMO=1000 playwright test",
"show-report": "npx playwright show-report",
"postinstall": "npx playwright install"
"postinstall": "script/post_install.sh"
},
"dependencies": {
"@axe-core/playwright": "4.8.3",
"@percy/cli": "1.27.7",
"@axe-core/playwright": "4.8.5",
"@percy/cli": "1.28.1",
"@percy/playwright": "1.0.4",
"@playwright/test": "1.41.1",
"@playwright/test": "1.42.1",
"async-wait-until": "2.0.12",
"axe-core": "4.8.3",
"axe-core": "4.8.4",
"chalk": "4.1.2",
"deepmerge": "4.3.1",
"dotenv": "16.3.2",
"dotenv": "16.4.5",
"form-data": "4.0.0",
"isomorphic-unfetch": "4.0.2",
"uuid": "9.0.1"
},
"devDependencies": {
"@types/uuid": "9.0.7",
"@typescript-eslint/eslint-plugin": "6.19.1",
"@typescript-eslint/parser": "6.19.1",
"@types/uuid": "9.0.8",
"@typescript-eslint/eslint-plugin": "7.2.0",
"@typescript-eslint/parser": "7.2.0",
"cross-env": "7.0.3",
"eslint": "8.56.0",
"prettier": "3.2.4",
"typescript": "5.3.3"
"eslint": "8.57.0",
"prettier": "3.2.5",
"typescript": "5.4.2"
}
}

View File

@ -0,0 +1,12 @@
#!/bin/bash
if [ -n "$PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD" ]; then
echo "Skipped browsers download for Playwright"
exit 0
fi
# Install needed Playwright browsers only -- chromium and firefox only for these are the ones being used by the tests.
# May add more browsers in the future.
# https://playwright.dev/docs/library#browser-downloads
npx playwright install chromium
npx playwright install firefox

View File

@ -136,7 +136,10 @@ export default class Client extends Client4 {
// Variable to hold cache
const clients: Record<string, ClientCache> = {};
async function makeClient(userRequest?: UserRequest, useCache = true): Promise<ClientCache> {
async function makeClient(
userRequest?: UserRequest,
opts: {useCache?: boolean; skipLog?: boolean} = {useCache: true, skipLog: false},
): Promise<ClientCache> {
const client = new Client();
client.setUrl(testConfig.baseURL);
@ -146,22 +149,24 @@ async function makeClient(userRequest?: UserRequest, useCache = true): Promise<C
}
const cacheKey = userRequest.username + userRequest.password;
if (useCache && clients[cacheKey] != null) {
if (opts?.useCache && clients[cacheKey] != null) {
return clients[cacheKey];
}
const userProfile = await client.login(userRequest.username, userRequest.password);
const user = {...userProfile, password: userRequest.password};
if (useCache) {
if (opts?.useCache) {
clients[cacheKey] = {client, user};
}
return {client, user};
} catch (err) {
// log an error for debugging
// eslint-disable-next-line no-console
console.log('makeClient', err);
if (!opts?.skipLog) {
// log an error for debugging
// eslint-disable-next-line no-console
console.log('makeClient', err);
}
return {client, user: null};
}
}

View File

@ -75,7 +75,7 @@ const onPremServerConfig = (): Partial<TestAdminConfig> => {
};
// Should be based only from the generated default config from ./server via "make config-reset"
// Based on v9.5 server
// Based on v9.7 server
const defaultServerConfig: AdminConfig = {
ServiceSettings: {
SiteURL: '',
@ -101,6 +101,7 @@ const defaultServerConfig: AdminConfig = {
EnableOAuthServiceProvider: true,
EnableIncomingWebhooks: true,
EnableOutgoingWebhooks: true,
EnableOutgoingOAuthConnections: false,
EnableCommands: true,
OutgoingIntegrationRequestsTimeout: 30,
EnablePostUsernameOverride: false,
@ -700,6 +701,7 @@ const defaultServerConfig: AdminConfig = {
CWSURL: 'https://customers.mattermost.com',
CWSAPIURL: 'https://portal.internal.prod.cloud.mattermost.com',
CWSMock: false,
Disable: false,
},
FeatureFlags: {
TestFeature: 'off',
@ -720,7 +722,8 @@ const defaultServerConfig: AdminConfig = {
CloudIPFiltering: false,
ConsumePostHook: false,
CloudAnnualRenewals: false,
OutgoingOAuthConnections: false,
CloudDedicatedExportUI: false,
WebSocketEventScope: false,
},
ImportSettings: {
Directory: './import',

View File

@ -92,11 +92,14 @@ export async function initSetup({
}
}
export async function getAdminClient() {
const {client: adminClient, user: adminUser} = await makeClient({
username: testConfig.adminUsername,
password: testConfig.adminPassword,
});
export async function getAdminClient(opts: {skipLog: boolean} = {skipLog: false}) {
const {client: adminClient, user: adminUser} = await makeClient(
{
username: testConfig.adminUsername,
password: testConfig.adminPassword,
},
opts,
);
return {adminClient, adminUser};
}

View File

@ -6,7 +6,7 @@ import os from 'node:os';
import chalk from 'chalk';
import {expect, TestInfo} from '@playwright/test';
import {illegalRe} from '@e2e-support/util';
import {duration, illegalRe, wait} from '@e2e-support/util';
import testConfig from '@e2e-test.config';
import {ScreenshotOptions, TestArgs} from '@e2e-types';
@ -23,6 +23,12 @@ export async function matchSnapshot(testInfo: TestInfo, testArgs: TestArgs, opti
return;
}
if (testConfig.snapshotEnabled || testConfig.percyEnabled) {
await testArgs.page.waitForLoadState('networkidle');
await testArgs.page.waitForLoadState('domcontentloaded');
await wait(duration.half_sec);
}
if (testConfig.snapshotEnabled) {
// Visual test with built-in snapshot
const filename = testInfo.title.replace(illegalRe, '').replace(/\s/g, '-').trim().toLowerCase();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@ -11,9 +11,9 @@
"@mattermost/types/*": ["../../webapp/platform/types/lib/*"],
"@e2e-support/*": ["support/*"],
"@e2e-test.config": ["test.config.ts"],
"@e2e-types": ["types.ts"],
},
"@e2e-types": ["types.ts"]
}
},
"include": ["./**/*"],
"exclude": ["playwright-report"],
"exclude": ["playwright-report"]
}

View File

@ -303,6 +303,7 @@ export type ServiceSettings = {
EnableOAuthServiceProvider: boolean;
EnableIncomingWebhooks: boolean;
EnableOutgoingWebhooks: boolean;
EnableOutgoingOAuthConnections: boolean;
EnableCommands: boolean;
OutgoingIntegrationRequestsTimeout: number;
EnablePostUsernameOverride: boolean;
@ -911,6 +912,7 @@ export type CloudSettings = {
CWSURL: string;
CWSAPIURL: string;
CWSMock: boolean;
Disable: boolean;
};
export type FeatureFlags = Record<string, string | boolean>;