mirror of
https://github.com/mattermost/mattermost.git
synced 2026-08-28 18:19:38 +08:00
fix tests with file server host (#38138)
This commit is contained in:
+3
@@ -27,6 +27,9 @@ describe('Upload Files', () => {
|
||||
// # Login as sysadmin
|
||||
cy.apiAdminLogin();
|
||||
|
||||
// # Ensure standard message display (download aria-label is omitted in compact)
|
||||
cy.apiSaveMessageDisplayPreference('clean');
|
||||
|
||||
// # Init setup
|
||||
cy.apiInitSetup().then((out) => {
|
||||
channelUrl = out.channelUrl;
|
||||
|
||||
@@ -47,15 +47,15 @@ function structuralEnv(): Record<string, string> {
|
||||
MM_EMAILSETTINGS_SMTPSERVER: INBUCKET_ALIAS,
|
||||
MM_EMAILSETTINGS_SMTPPORT: String(INBUCKET_SMTP_PORT),
|
||||
...(process.env.MM_LICENSE ? {MM_LICENSE: process.env.MM_LICENSE} : {}),
|
||||
// Overrides (not merges) SERVER_ENV_BASELINE's own value for this same key — appends the
|
||||
// network's gateway IP so the SSRF guard also allows fetching from file_server.ts's mock
|
||||
// file server, reachable at that address (see test_config.ts). Only known once the
|
||||
// network is up (testConfig.testcontainersNetworkGatewayIp is set by stack.ts's
|
||||
// startStack() before this container ever starts), so falls back to the baseline's own
|
||||
// value verbatim on the off chance this ever runs without it.
|
||||
MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS: testConfig.testcontainersNetworkGatewayIp
|
||||
? `${SERVER_ENV_BASELINE.MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS} ${testConfig.testcontainersNetworkGatewayIp}`
|
||||
: SERVER_ENV_BASELINE.MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS,
|
||||
// Replaces the baseline for this key: appends mock file-server hosts (host.docker.internal
|
||||
// and the bridge gateway IP, set by startStack() once the network is up).
|
||||
MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS: [
|
||||
SERVER_ENV_BASELINE.MM_SERVICESETTINGS_ALLOWEDUNTRUSTEDINTERNALCONNECTIONS,
|
||||
'host.docker.internal',
|
||||
testConfig.testcontainersNetworkGatewayIp,
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(' '),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -85,6 +85,8 @@ export async function startMattermostContainer(
|
||||
.withNetworkMode(networkName)
|
||||
.withNetworkAliases(MATTERMOST_ALIAS)
|
||||
.withLabels(TESTCONTAINERS_LABELS)
|
||||
// Ensures host.docker.internal resolves to the Docker host (via host-gateway).
|
||||
.withExtraHosts([{host: 'host.docker.internal', ipAddress: 'host-gateway'}])
|
||||
.withExposedPorts(MATTERMOST_PORT)
|
||||
.withEnvironment(env)
|
||||
.withStartupTimeout(5 * 60_000)
|
||||
|
||||
@@ -8,6 +8,9 @@ import {test} from './test_fixture';
|
||||
|
||||
import {testConfig} from '@/test_config';
|
||||
|
||||
/** Hostname containers use to reach the Docker host. */
|
||||
export const DOCKER_HOST_INTERNAL = 'host.docker.internal';
|
||||
|
||||
/**
|
||||
* Starts a server that serves files from ./asset. When run from the monorepo, this will serve files from
|
||||
* e2e-tests/playwright/asset.
|
||||
@@ -63,10 +66,18 @@ export function setupFileServer(): Promise<string> {
|
||||
});
|
||||
}
|
||||
|
||||
// localhost isn't reachable from inside the Mattermost container in `testcontainers` mode (it resolves to
|
||||
// the container's own loopback, not the host's). testcontainersNetworkGatewayIp is reachable
|
||||
// from both the container and the host-side browser, so it works as a single URL for both — this
|
||||
// server binds to 0.0.0.0, not just loopback, to accept the former.
|
||||
function fileServerHost(): string {
|
||||
return testConfig.useTestContainers ? testConfig.testcontainersNetworkGatewayIp : 'localhost';
|
||||
/**
|
||||
* Host used in file-server URLs embedded in posts. Must be reachable from both the host-side
|
||||
* browser (Markdown images load directly) and the Mattermost container (link previews / metadata).
|
||||
* On macOS/Windows the bridge gateway does not reach host listeners, so use host.docker.internal;
|
||||
* on Linux use the bridge gateway IP (works both sides; host.docker.internal is often absent from host DNS).
|
||||
*/
|
||||
export function fileServerHost(): string {
|
||||
if (!testConfig.useTestContainers) {
|
||||
return 'localhost';
|
||||
}
|
||||
if (process.platform === 'darwin' || process.platform === 'win32') {
|
||||
return DOCKER_HOST_INTERNAL;
|
||||
}
|
||||
return testConfig.testcontainersNetworkGatewayIp || DOCKER_HOST_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ const {createServer} = require('http');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const PORT = Number(process.env.PORT) || 3011;
|
||||
// PORT=0 must request an ephemeral port — don't treat 0 as falsy and fall back to 3011.
|
||||
const PORT = process.env.PORT !== undefined && process.env.PORT !== '' ? Number(process.env.PORT) : 3011;
|
||||
const ASSET_DIR = process.env.ASSET_DIR || path.join(__dirname, 'asset');
|
||||
|
||||
if (process.argv[2]) {
|
||||
|
||||
@@ -176,7 +176,6 @@ test.describe('Post list initial scroll in read channel', () => {
|
||||
|
||||
async function waitForScrollToSettle(watcher: PostListScrollWatcher) {
|
||||
await channelsPage.centerView.toBeVisible();
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// # Wait until the post list hasn't scrolled for 500ms before returning results
|
||||
return watcher.waitForObservations(500);
|
||||
|
||||
@@ -194,8 +194,6 @@ test.describe('Post list initial scroll in unread channel', () => {
|
||||
await channelsPage.goto(team.name, 'town-square');
|
||||
await channelsPage.centerView.getLastPost();
|
||||
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// * Verify that the channel starts as unread
|
||||
await channelsPage.sidebarLeft.assertItemUnread(channel.name);
|
||||
|
||||
@@ -220,7 +218,6 @@ test.describe('Post list initial scroll in unread channel', () => {
|
||||
|
||||
async function waitForScrollToSettle(watcher: PostListScrollWatcher) {
|
||||
await channelsPage.centerView.toBeVisible();
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// # Wait until the post list hasn't scrolled for 500ms before returning results
|
||||
return watcher.waitForObservations(500);
|
||||
|
||||
@@ -281,7 +281,6 @@ test.describe('Post list scroll to permalink', () => {
|
||||
|
||||
async function waitForScrollToSettle(watcher: PostListScrollWatcher) {
|
||||
await channelsPage.centerView.toBeVisible();
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// # Wait until the post list hasn't scrolled for 500ms before returning results
|
||||
return watcher.waitForObservations(500);
|
||||
|
||||
@@ -38,9 +38,6 @@ test.describe('Post height', () => {
|
||||
});
|
||||
|
||||
// # Enable SVG rendering and let the server fetch metadata from the mock file server.
|
||||
// AllowedUntrustedInternalConnections only takes effect in `external` mode here — in
|
||||
// `testcontainers` mode it's fixed at boot via an env var, and a PatchConfig on an env-controlled
|
||||
// field is accepted but has no real effect.
|
||||
await adminClient.patchConfig({
|
||||
ServiceSettings: {
|
||||
EnableSVGs: true,
|
||||
@@ -465,9 +462,6 @@ test.describe('Post height', () => {
|
||||
await testCase.additionalCheck({postComponent});
|
||||
}
|
||||
|
||||
// # Wait for all network requests to finish
|
||||
await page.waitForLoadState('networkidle');
|
||||
|
||||
// * Verify no height changes were detected
|
||||
expect(await sizeWatcher.getObservations()).toHaveLength(1);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user