Skip to content

Commit 58877bf

Browse files
test(e2e): stabilize Zephyr specs and enable public links in CI.
Fix flaky help menu refresh, harden media preview and window position tests, and enable FileSettings.EnablePublicLink on E2E servers before Playwright runs. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent d44be2e commit 58877bf

6 files changed

Lines changed: 351 additions & 131 deletions

File tree

.github/workflows/e2e-functional-template.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,10 @@ jobs:
287287
npm ci
288288
cd e2e && npm ci
289289
290+
- name: e2e/enable-public-links
291+
if: env.MM_TEST_SERVER_URL != ''
292+
run: node e2e/scripts/enable-public-links.mjs
293+
290294
- name: e2e/suppress-macos-dialogs
291295
if: runner.os == 'macOS'
292296
run: |

e2e/helpers/helpMenuLinks.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ export async function patchHelpMenuRemoteInfo(
3333
}
3434
refs.ServerManager.updateRemoteInfo(serverId, nextRemoteInfo);
3535

36-
ipcMain.emit('emit-configuration', null);
36+
const configData = refs.Config?.data ?? refs.Config?.combinedData;
37+
if (!configData) {
38+
throw new Error('Config.data is not available for menu refresh');
39+
}
40+
41+
ipcMain.emit('emit-configuration', null, configData);
3742
}, patch);
3843
}
3944

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
2+
// See LICENSE.txt for license information.
3+
4+
import {apiLogin, apiRequest} from './client';
5+
import {getTestServerCredentials} from './credentials';
6+
7+
type ServerConfig = {
8+
FileSettings?: {
9+
EnablePublicLink?: boolean;
10+
};
11+
ServiceSettings?: {
12+
SiteURL?: string;
13+
};
14+
};
15+
16+
export async function isPublicLinkEnabled(credentials = getTestServerCredentials()): Promise<boolean> {
17+
const token = await apiLogin(credentials.baseUrl, credentials.username, credentials.password);
18+
const config = await apiRequest<ServerConfig>(credentials.baseUrl, token, '/api/v4/config');
19+
return config.FileSettings?.EnablePublicLink === true;
20+
}
21+
22+
export async function enablePublicLinks(credentials = getTestServerCredentials()): Promise<boolean> {
23+
const token = await apiLogin(credentials.baseUrl, credentials.username, credentials.password);
24+
const config = await apiRequest<ServerConfig>(credentials.baseUrl, token, '/api/v4/config');
25+
26+
if (config.FileSettings?.EnablePublicLink === true) {
27+
return false;
28+
}
29+
30+
const siteURL = config.ServiceSettings?.SiteURL ?? credentials.baseUrl;
31+
await apiRequest(credentials.baseUrl, token, '/api/v4/config', {
32+
method: 'PUT',
33+
body: JSON.stringify({
34+
...config,
35+
ServiceSettings: {...config.ServiceSettings, SiteURL: siteURL},
36+
FileSettings: {...config.FileSettings, EnablePublicLink: true},
37+
}),
38+
});
39+
40+
return true;
41+
}
42+
43+
export async function getFilePublicLink(fileId: string, credentials = getTestServerCredentials()): Promise<string> {
44+
const token = await apiLogin(credentials.baseUrl, credentials.username, credentials.password);
45+
const response = await apiRequest<{link: string}>(
46+
credentials.baseUrl,
47+
token,
48+
`/api/v4/files/${fileId}/link`,
49+
);
50+
return response.link;
51+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
2+
// See LICENSE.txt for license information.
3+
4+
const baseUrl = (process.env.MM_TEST_SERVER_URL ?? '').replace(/\/$/, '');
5+
const username = process.env.MM_TEST_USER_NAME;
6+
const password = process.env.MM_TEST_PASSWORD;
7+
8+
if (!baseUrl || !username || !password) {
9+
console.error('MM_TEST_SERVER_URL, MM_TEST_USER_NAME, and MM_TEST_PASSWORD are required');
10+
process.exit(1);
11+
}
12+
13+
async function apiLogin() {
14+
const response = await fetch(`${baseUrl}/api/v4/users/login`, {
15+
method: 'POST',
16+
headers: {'Content-Type': 'application/json'},
17+
body: JSON.stringify({login_id: username, password}),
18+
});
19+
if (!response.ok) {
20+
throw new Error(`Login failed: ${response.status} ${await response.text()}`);
21+
}
22+
23+
const token = response.headers.get('Token') ?? response.headers.get('token');
24+
if (token) {
25+
return token;
26+
}
27+
28+
const body = await response.json();
29+
if (body.token) {
30+
return body.token;
31+
}
32+
33+
throw new Error('Login did not return a session token');
34+
}
35+
36+
async function apiRequest(token, path, init = {}) {
37+
const response = await fetch(`${baseUrl}${path}`, {
38+
...init,
39+
headers: {
40+
Authorization: `Bearer ${token}`,
41+
'Content-Type': 'application/json',
42+
...init.headers,
43+
},
44+
});
45+
if (!response.ok) {
46+
throw new Error(`${init.method ?? 'GET'} ${path} failed: ${response.status} ${await response.text()}`);
47+
}
48+
return response.json();
49+
}
50+
51+
async function main() {
52+
const token = await apiLogin();
53+
const config = await apiRequest(token, '/api/v4/config');
54+
55+
if (config.FileSettings?.EnablePublicLink === true) {
56+
console.log('Public links already enabled on the E2E server');
57+
return;
58+
}
59+
60+
const siteURL = config.ServiceSettings?.SiteURL ?? baseUrl;
61+
await apiRequest(token, '/api/v4/config', {
62+
method: 'PUT',
63+
body: JSON.stringify({
64+
...config,
65+
ServiceSettings: {...config.ServiceSettings, SiteURL: siteURL},
66+
FileSettings: {...config.FileSettings, EnablePublicLink: true},
67+
}),
68+
});
69+
70+
const updated = await apiRequest(token, '/api/v4/config');
71+
if (updated.FileSettings?.EnablePublicLink !== true) {
72+
throw new Error('Failed to enable public links on the E2E server');
73+
}
74+
75+
console.log('Enabled public links on the E2E server');
76+
}
77+
78+
main().catch((error) => {
79+
console.error(error);
80+
process.exit(1);
81+
});

0 commit comments

Comments
 (0)