[MM-39852] Setup docker image to run in CI for E2E (#1946)
* [MM-39852] Setup docker image to run in CI for E2E * Setup remote docker * Install docker * Trying this * And this * how about this * this * Okay this * dis one * sdfsagsdags * Now? * aaaaaaa * asdasdasd * i am dumb * blank * Please work * Lint fix * Forgot to update a couple things * OOPS * Testing something since this one is still failing * Trying robotjs instead * test * Remove stop docker * Try without the admin user (since apparently turning off admin notices didn't work) * Remove console statement Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
This commit is contained in:
parent
6e8455e80e
commit
4a05b7c8d5
|
@ -9,6 +9,13 @@ orbs:
|
|||
owasp: entur/owasp@0.0.10
|
||||
|
||||
executors:
|
||||
check-image:
|
||||
working_directory: ~/mattermost-desktop
|
||||
docker:
|
||||
- image: electronuserland/builder:wine-chrome
|
||||
environment:
|
||||
TAR_OPTIONS: --no-same-owner
|
||||
- image: mattermost/mattermost-preview
|
||||
wine-chrome:
|
||||
working_directory: ~/mattermost-desktop
|
||||
docker:
|
||||
|
@ -127,12 +134,18 @@ commands:
|
|||
path: /tmp/artifacts
|
||||
jobs:
|
||||
check:
|
||||
executor: wine-chrome
|
||||
executor: check-image
|
||||
steps:
|
||||
- checkout
|
||||
- update_image:
|
||||
apt_opts: "--no-install-recommends"
|
||||
- run: wget https://github.com/mattermost/mmctl/releases/download/v6.0.0/linux_amd64.tar && tar -xvf linux_amd64.tar
|
||||
- run: npm run check-types
|
||||
- run:
|
||||
name: Setup MM Docker Image
|
||||
command: npm run test:docker
|
||||
environment:
|
||||
MMCTL_PATH: ./mmctl
|
||||
- run: ELECTRON_DISABLE_SANDBOX=1 xvfb-run npm run test
|
||||
- run: mkdir -p /tmp/test-results
|
||||
- run: cp test-results.xml /tmp/test-results/
|
||||
|
|
|
@ -27,13 +27,12 @@ const electronBinaryPath = (() => {
|
|||
const userDataDir = path.join(sourceRootDir, 'e2e/testUserData/');
|
||||
const configFilePath = path.join(userDataDir, 'config.json');
|
||||
const boundsInfoPath = path.join(userDataDir, 'bounds-info.json');
|
||||
const mattermostURL = 'http://example.com/';
|
||||
const exampleURL = 'http://example.com/';
|
||||
const mattermostURL = 'http://localhost:8065/';
|
||||
|
||||
const demoConfig = {
|
||||
version: 3,
|
||||
teams: [{
|
||||
const exampleTeam = {
|
||||
name: 'example',
|
||||
url: mattermostURL,
|
||||
url: exampleURL,
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
|
@ -53,7 +52,8 @@ const demoConfig = {
|
|||
},
|
||||
],
|
||||
lastActiveTab: 0,
|
||||
}, {
|
||||
};
|
||||
const githubTeam = {
|
||||
name: 'github',
|
||||
url: 'https://github.com/',
|
||||
order: 1,
|
||||
|
@ -75,7 +75,11 @@ const demoConfig = {
|
|||
},
|
||||
],
|
||||
lastActiveTab: 0,
|
||||
}],
|
||||
};
|
||||
|
||||
const demoConfig = {
|
||||
version: 3,
|
||||
teams: [exampleTeam, githubTeam],
|
||||
showTrayIcon: false,
|
||||
trayIconTheme: 'light',
|
||||
minimizeToTray: false,
|
||||
|
@ -93,13 +97,23 @@ const demoConfig = {
|
|||
spellCheckerLocales: [],
|
||||
};
|
||||
|
||||
const demoMattermostConfig = {
|
||||
...demoConfig,
|
||||
teams: [{
|
||||
...exampleTeam,
|
||||
url: mattermostURL,
|
||||
}, githubTeam],
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
sourceRootDir,
|
||||
configFilePath,
|
||||
userDataDir,
|
||||
boundsInfoPath,
|
||||
exampleURL,
|
||||
mattermostURL,
|
||||
demoConfig,
|
||||
demoMattermostConfig,
|
||||
|
||||
cleanTestConfig() {
|
||||
[configFilePath, boundsInfoPath].forEach((file) => {
|
||||
|
@ -171,6 +185,15 @@ module.exports = {
|
|||
return map;
|
||||
},
|
||||
|
||||
async loginToMattermost(window) {
|
||||
await window.waitForSelector('#loginId');
|
||||
await window.waitForSelector('#loginPassword');
|
||||
await window.waitForSelector('#loginButton');
|
||||
await window.type('#loginId', 'user-1');
|
||||
await window.type('#loginPassword', 'SampleUs@r-1');
|
||||
await window.click('#loginButton');
|
||||
},
|
||||
|
||||
addClientCommands(client) {
|
||||
client.addCommand('loadSettingsPage', function async() {
|
||||
ipcRenderer.send(SHOW_SETTINGS_WINDOW);
|
||||
|
|
|
@ -71,7 +71,7 @@ describe('menu_bar/dropdown', function desc() {
|
|||
const mainWindow = await this.app.firstWindow();
|
||||
const browserWindow = await this.app.browserWindow(mainWindow);
|
||||
|
||||
let firstViewIsAttached = await browserWindow.evaluate((window, url) => Boolean(window.getBrowserViews().find((view) => view.webContents.getURL() === url)), env.mattermostURL);
|
||||
let firstViewIsAttached = await browserWindow.evaluate((window, url) => Boolean(window.getBrowserViews().find((view) => view.webContents.getURL() === url)), env.exampleURL);
|
||||
firstViewIsAttached.should.be.true;
|
||||
let secondViewIsAttached = await browserWindow.evaluate((window) => Boolean(window.getBrowserViews().find((view) => view.webContents.getURL() === 'https://github.com/')));
|
||||
secondViewIsAttached.should.be.false;
|
||||
|
@ -81,7 +81,7 @@ describe('menu_bar/dropdown', function desc() {
|
|||
await mainView.click('.TeamDropdownButton');
|
||||
await dropdownView.click('.TeamDropdown button.TeamDropdown__button:nth-child(2)');
|
||||
|
||||
firstViewIsAttached = await browserWindow.evaluate((window, url) => Boolean(window.getBrowserViews().find((view) => view.webContents.getURL() === url)), env.mattermostURL);
|
||||
firstViewIsAttached = await browserWindow.evaluate((window, url) => Boolean(window.getBrowserViews().find((view) => view.webContents.getURL() === url)), env.exampleURL);
|
||||
firstViewIsAttached.should.be.false;
|
||||
secondViewIsAttached = await browserWindow.evaluate((window) => Boolean(window.getBrowserViews().find((view) => view.webContents.getURL() === 'https://github.com/')));
|
||||
secondViewIsAttached.should.be.true;
|
||||
|
|
|
@ -23,7 +23,7 @@ async function setupPromise(window, id) {
|
|||
describe('mattermost', function desc() {
|
||||
this.timeout(30000);
|
||||
|
||||
const config = env.demoConfig;
|
||||
const config = env.demoMattermostConfig;
|
||||
|
||||
beforeEach(async () => {
|
||||
env.cleanDataDir();
|
||||
|
@ -41,14 +41,14 @@ describe('mattermost', function desc() {
|
|||
}
|
||||
});
|
||||
|
||||
// TODO: enable when we have a server to test against
|
||||
it.skip('MM-T813 Control+F should focus the search bar in Mattermost', async () => {
|
||||
it('MM-T813 Control+F should focus the search bar in Mattermost', async () => {
|
||||
const loadingScreen = this.app.windows().find((window) => window.url().includes('loadingScreen'));
|
||||
await loadingScreen.waitForSelector('.LoadingScreen', {state: 'hidden'});
|
||||
const firstServer = this.serverMap[`${config.teams[0].name}___TAB_MESSAGING`].win;
|
||||
await env.loginToMattermost(firstServer);
|
||||
await firstServer.waitForSelector('#searchBox');
|
||||
await firstServer.press('body', process.platform === 'darwin' ? 'Meta+F' : 'Control+F');
|
||||
robot.keyTap('f', [process.platform === 'darwin' ? 'command' : 'control']);
|
||||
await asyncSleep(500);
|
||||
const isFocused = await firstServer.$eval('#searchBox', (el) => el === document.activeElement);
|
||||
isFocused.should.be.true;
|
||||
const text = await firstServer.inputValue('#searchBox');
|
||||
|
|
|
@ -47,7 +47,7 @@ describe('EditServerModal', function desc() {
|
|||
const savedConfig = JSON.parse(fs.readFileSync(env.configFilePath, 'utf8'));
|
||||
savedConfig.teams.should.deep.contain({
|
||||
name: 'example',
|
||||
url: env.mattermostURL,
|
||||
url: env.exampleURL,
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ describe('EditServerModal', function desc() {
|
|||
const savedConfig = JSON.parse(fs.readFileSync(env.configFilePath, 'utf8'));
|
||||
savedConfig.teams.should.deep.contain({
|
||||
name: 'example',
|
||||
url: env.mattermostURL,
|
||||
url: env.exampleURL,
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
|
@ -119,7 +119,7 @@ describe('EditServerModal', function desc() {
|
|||
const savedConfig = JSON.parse(fs.readFileSync(env.configFilePath, 'utf8'));
|
||||
savedConfig.teams.should.not.deep.contain({
|
||||
name: 'example',
|
||||
url: env.mattermostURL,
|
||||
url: env.exampleURL,
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
|
@ -142,7 +142,7 @@ describe('EditServerModal', function desc() {
|
|||
});
|
||||
savedConfig.teams.should.deep.contain({
|
||||
name: 'NewTestTeam',
|
||||
url: env.mattermostURL,
|
||||
url: env.exampleURL,
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
|
@ -175,7 +175,7 @@ describe('EditServerModal', function desc() {
|
|||
const savedConfig = JSON.parse(fs.readFileSync(env.configFilePath, 'utf8'));
|
||||
savedConfig.teams.should.not.deep.contain({
|
||||
name: 'example',
|
||||
url: env.mattermostURL,
|
||||
url: env.exampleURL,
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
|
@ -233,7 +233,7 @@ describe('EditServerModal', function desc() {
|
|||
const savedConfig = JSON.parse(fs.readFileSync(env.configFilePath, 'utf8'));
|
||||
savedConfig.teams.should.not.deep.contain({
|
||||
name: 'example',
|
||||
url: env.mattermostURL,
|
||||
url: env.exampleURL,
|
||||
order: 0,
|
||||
tabs: [
|
||||
{
|
||||
|
|
|
@ -70,7 +70,10 @@ describe('RemoveServerModal', function desc() {
|
|||
});
|
||||
|
||||
it('MM-T4390_4 should disappear on click background', async () => {
|
||||
// ignore any target closed error
|
||||
try {
|
||||
await removeServerView.click('.modal', {position: {x: 20, y: 20}});
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
await asyncSleep(1000);
|
||||
const existing = Boolean(await this.app.windows().find((window) => window.url().includes('removeServer')));
|
||||
existing.should.be.false;
|
||||
|
|
|
@ -41,6 +41,7 @@ describe('Settings', function desc() {
|
|||
predicate: (window) => window.url().includes('settings'),
|
||||
});
|
||||
await settingsWindow.waitForSelector('.settingsPage.container');
|
||||
await settingsWindow.waitForSelector('#inputAutoStart');
|
||||
const existing = await settingsWindow.isVisible('#inputAutoStart');
|
||||
existing.should.equal(expected);
|
||||
});
|
||||
|
@ -56,6 +57,7 @@ describe('Settings', function desc() {
|
|||
predicate: (window) => window.url().includes('settings'),
|
||||
});
|
||||
await settingsWindow.waitForSelector('.settingsPage.container');
|
||||
await settingsWindow.waitForSelector('#inputShowTrayIcon');
|
||||
const existing = await settingsWindow.isVisible('#inputShowTrayIcon');
|
||||
existing.should.equal(expected);
|
||||
});
|
||||
|
|
|
@ -60,7 +60,7 @@ describe('config', function desc() {
|
|||
const Config = require('../../../src/common/config').Config;
|
||||
const newConfig = new Config(env.configFilePath);
|
||||
const oldConfig = {
|
||||
url: env.mattermostURL,
|
||||
url: env.exampleURL,
|
||||
};
|
||||
fs.writeFileSync(env.configFilePath, JSON.stringify(oldConfig));
|
||||
this.app = await env.getApp();
|
||||
|
|
42
package-lock.json
generated
42
package-lock.json
generated
|
@ -60,6 +60,7 @@
|
|||
"@typescript-eslint/parser": "4.28.0",
|
||||
"7zip-bin": "^4.1.0",
|
||||
"awesome-node-loader": "^1.1.1",
|
||||
"axios": "^0.24.0",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^8.0.4",
|
||||
"chai": "^4.2.0",
|
||||
|
@ -8114,6 +8115,15 @@
|
|||
"loader-utils": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.4"
|
||||
}
|
||||
},
|
||||
"node_modules/babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
|
@ -16307,12 +16317,23 @@
|
|||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz",
|
||||
"integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==",
|
||||
"version": "1.14.7",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/font-awesome": {
|
||||
|
@ -38096,6 +38117,15 @@
|
|||
"loader-utils": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.24.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
|
||||
"integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.4"
|
||||
}
|
||||
},
|
||||
"babel-code-frame": {
|
||||
"version": "6.26.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||
|
@ -44736,9 +44766,9 @@
|
|||
}
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.12.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz",
|
||||
"integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==",
|
||||
"version": "1.14.7",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
|
||||
"integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
|
||||
"dev": true
|
||||
},
|
||||
"font-awesome": {
|
||||
|
|
10
package.json
10
package.json
|
@ -38,6 +38,7 @@
|
|||
"watch:main": "node scripts/watch_main_and_preload.js",
|
||||
"watch:renderer": "webpack-dev-server --config webpack.config.renderer.js",
|
||||
"test": "npm-run-all lint:js test:unit test:e2e",
|
||||
"test:docker": "node scripts/setup_e2e_docker.js",
|
||||
"test:e2e": "cross-env NODE_ENV=test npm-run-all build build-robotjs test:e2e:build test:e2e:run",
|
||||
"test:e2e:nobuild": "cross-env NODE_ENV=test npm-run-all test:e2e:build test:e2e:run",
|
||||
"test:e2e:build": "webpack-cli --bail --config webpack.config.test.js",
|
||||
|
@ -75,11 +76,15 @@
|
|||
"src/common/**/*.ts",
|
||||
"src/main/**/*.ts"
|
||||
],
|
||||
"testMatch": ["**/src/**/*.test.js"],
|
||||
"testMatch": [
|
||||
"**/src/**/*.test.js"
|
||||
],
|
||||
"globals": {
|
||||
"__HASH_VERSION__": "5.0.0"
|
||||
},
|
||||
"setupFiles": ["./src/jestSetup.js"]
|
||||
"setupFiles": [
|
||||
"./src/jestSetup.js"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.14.5",
|
||||
|
@ -106,6 +111,7 @@
|
|||
"@typescript-eslint/parser": "4.28.0",
|
||||
"7zip-bin": "^4.1.0",
|
||||
"awesome-node-loader": "^1.1.1",
|
||||
"axios": "^0.24.0",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^8.0.4",
|
||||
"chai": "^4.2.0",
|
||||
|
|
59
scripts/setup_e2e_docker.js
Normal file
59
scripts/setup_e2e_docker.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
const {spawn, exec} = require('child_process');
|
||||
|
||||
const axios = require('axios');
|
||||
|
||||
const mmctlPath = process.env.MMCTL_PATH || 'mmctl';
|
||||
|
||||
const ping = setInterval(async () => {
|
||||
try {
|
||||
const pingRequest = await axios.get('http://localhost:8065/api/v4/system/ping');
|
||||
if (pingRequest.status === 200) {
|
||||
const addUserRequest = await axios.post(
|
||||
'http://localhost:8065/api/v4/users',
|
||||
{
|
||||
email: 'test@test.com',
|
||||
username: 'admin1',
|
||||
password: 'Sys@dmin123',
|
||||
allow_marketing: false,
|
||||
});
|
||||
if (addUserRequest.status === 201) {
|
||||
clearInterval(ping);
|
||||
|
||||
exec('echo "Sys@dmin123" > passfile', () => {
|
||||
const mmctlauth = spawn(mmctlPath, ['auth', 'login', 'http://localhost:8065', '--name', 'local-server', '--username', 'admin1', '--password-file', 'passfile']);
|
||||
mmctlauth.stdout.on('data', (data) => {
|
||||
console.log(`${data}`);
|
||||
});
|
||||
|
||||
mmctlauth.stderr.on('data', (data) => {
|
||||
console.log(`ERROR: ${data}`);
|
||||
});
|
||||
|
||||
mmctlauth.on('close', () => {
|
||||
const sampledata = spawn(mmctlPath, ['sampledata']);
|
||||
sampledata.stdout.on('data', (data) => {
|
||||
console.log(`${data}`);
|
||||
});
|
||||
|
||||
sampledata.stderr.on('data', (data) => {
|
||||
console.log(`ERROR: ${data}`);
|
||||
});
|
||||
|
||||
sampledata.on('close', () => {
|
||||
exec(`${mmctlPath} config set AnnouncementSettings.UserNoticesEnabled false`, (err, stdout, stderr) => {
|
||||
console.log(err, stdout, stderr);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.log(`ERROR: Trying to contact server, got ${pingRequest.status}`);
|
||||
}
|
||||
} catch {
|
||||
console.log('waiting for server to respond...');
|
||||
}
|
||||
}, 1000);
|
Loading…
Reference in a new issue