Automated browser testing (#1415)
* Move automated api tests to api directory * First pass at automated browser testing
This commit is contained in:
13
test/automated/api/admin.test.js
Normal file
13
test/automated/api/admin.test.js
Normal file
@@ -0,0 +1,13 @@
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
|
||||
|
||||
|
||||
test('correct number of log entries exist', (done) => {
|
||||
request.get('/api/admin/logs').auth('admin', 'abc123').expect(200)
|
||||
.then((res) => {
|
||||
// expect(res.body).toHaveLength(8);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
40
test/automated/api/chat.test.js
Normal file
40
test/automated/api/chat.test.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const { test } = require('@jest/globals');
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
|
||||
const registerChat = require('./lib/chat').registerChat;
|
||||
const sendChatMessage = require('./lib/chat').sendChatMessage;
|
||||
|
||||
var userDisplayName;
|
||||
const message = Math.floor(Math.random() * 100) + ' test 123';
|
||||
|
||||
const testMessage = {
|
||||
body: message,
|
||||
type: 'CHAT',
|
||||
};
|
||||
|
||||
test('can send a chat message', async (done) => {
|
||||
const registration = await registerChat();
|
||||
const accessToken = registration.accessToken;
|
||||
userDisplayName = registration.displayName;
|
||||
|
||||
sendChatMessage(testMessage, accessToken, done);
|
||||
});
|
||||
|
||||
test('can fetch chat messages', async (done) => {
|
||||
const res = await request
|
||||
.get('/api/admin/chat/messages')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
|
||||
const expectedBody = `${testMessage.body}`
|
||||
const message = res.body.filter(function (msg) {
|
||||
return msg.body === expectedBody
|
||||
})[0];
|
||||
|
||||
expect(message.body).toBe(expectedBody);
|
||||
expect(message.user.displayName).toBe(userDisplayName);
|
||||
expect(message.type).toBe(testMessage.type);
|
||||
|
||||
done();
|
||||
});
|
||||
42
test/automated/api/chatmoderation.test.js
Normal file
42
test/automated/api/chatmoderation.test.js
Normal file
@@ -0,0 +1,42 @@
|
||||
const { test } = require('@jest/globals');
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
|
||||
const registerChat = require('./lib/chat').registerChat;
|
||||
const sendChatMessage = require('./lib/chat').sendChatMessage;
|
||||
|
||||
const testVisibilityMessage = {
|
||||
body: "message " + Math.floor(Math.random() * 100),
|
||||
type: 'CHAT',
|
||||
};
|
||||
|
||||
test('can send a chat message', async (done) => {
|
||||
const registration = await registerChat();
|
||||
const accessToken = registration.accessToken;
|
||||
|
||||
sendChatMessage(testVisibilityMessage, accessToken, done);
|
||||
});
|
||||
|
||||
test('verify we can make API call to mark message as hidden', async (done) => {
|
||||
const res = await request.get('/api/admin/chat/messages').auth('admin', 'abc123').expect(200)
|
||||
|
||||
const message = res.body[0];
|
||||
const messageId = message.id;
|
||||
await request.post('/api/admin/chat/updatemessagevisibility')
|
||||
.auth('admin', 'abc123')
|
||||
.send({ "idArray": [messageId], "visible": false }).expect(200);
|
||||
done();
|
||||
});
|
||||
|
||||
test('verify message has become hidden', async (done) => {
|
||||
const res = await request.get('/api/admin/chat/messages')
|
||||
.expect(200)
|
||||
.auth('admin', 'abc123')
|
||||
|
||||
const message = res.body.filter(obj => {
|
||||
return obj.body === `${testVisibilityMessage.body}`;
|
||||
});
|
||||
expect(message.length).toBe(1);
|
||||
expect(message[0].hiddenAt).toBeTruthy();
|
||||
done();
|
||||
});
|
||||
118
test/automated/api/chatusers.test.js
Normal file
118
test/automated/api/chatusers.test.js
Normal file
@@ -0,0 +1,118 @@
|
||||
const { test } = require('@jest/globals');
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
const WebSocket = require('ws');
|
||||
const fs = require('fs');
|
||||
|
||||
const registerChat = require('./lib/chat').registerChat;
|
||||
const sendChatMessage = require('./lib/chat').sendChatMessage;
|
||||
|
||||
const testVisibilityMessage = {
|
||||
body: 'message ' + Math.floor(Math.random() * 100),
|
||||
type: 'CHAT',
|
||||
};
|
||||
|
||||
var userId;
|
||||
var accessToken;
|
||||
test('can register a user', async (done) => {
|
||||
const registration = await registerChat();
|
||||
userId = registration.id;
|
||||
accessToken = registration.accessToken;
|
||||
done();
|
||||
});
|
||||
|
||||
test('can send a chat message', async (done) => {
|
||||
sendChatMessage(testVisibilityMessage, accessToken, done);
|
||||
});
|
||||
|
||||
test('can disable a user', async (done) => {
|
||||
// To allow for visually being able to see the test hiding the
|
||||
// message add a short delay.
|
||||
await new Promise((r) => setTimeout(r, 1500));
|
||||
|
||||
await request
|
||||
.post('/api/admin/chat/users/setenabled')
|
||||
.send({ userId: userId, enabled: false })
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
done();
|
||||
});
|
||||
|
||||
test('verify user is disabled', async (done) => {
|
||||
const response = await request
|
||||
.get('/api/admin/chat/users/disabled')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
const tokenCheck = response.body.filter((user) => user.id === userId);
|
||||
expect(tokenCheck).toHaveLength(1);
|
||||
done();
|
||||
});
|
||||
|
||||
test('verify messages from user are hidden', async (done) => {
|
||||
const response = await request
|
||||
.get('/api/admin/chat/messages')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
const message = response.body.filter((obj) => {
|
||||
return obj.user.id === userId;
|
||||
});
|
||||
expect(message[0].hiddenAt).toBeTruthy();
|
||||
done();
|
||||
});
|
||||
|
||||
test('can re-enable a user', async (done) => {
|
||||
await request
|
||||
.post('/api/admin/chat/users/setenabled')
|
||||
.send({ userId: userId, enabled: true })
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
done();
|
||||
});
|
||||
|
||||
test('verify user is enabled', async (done) => {
|
||||
const response = await request
|
||||
.get('/api/admin/chat/users/disabled')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
const tokenCheck = response.body.filter((user) => user.id === userId);
|
||||
expect(tokenCheck).toHaveLength(0);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
test('verify user list is populated', async (done) => {
|
||||
const ws = new WebSocket(
|
||||
`ws://localhost:8080/ws?accessToken=${accessToken}`,
|
||||
{
|
||||
origin: 'http://localhost:8080',
|
||||
}
|
||||
);
|
||||
|
||||
ws.on('open', async function open() {
|
||||
const response = await request
|
||||
.get('/api/admin/chat/clients')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.length).toBeGreaterThan(0);
|
||||
|
||||
// Optionally, if GeoIP is configured, check the location property.
|
||||
if (fs.existsSync('../../data/GeoLite2-City.mmdb')) {
|
||||
expect(response.body[0].geo.regionName).toBe('Localhost');
|
||||
} else {
|
||||
console.warn('GeoIP Data is not supplied. Skipping test. See https://owncast.online/docs/viewers/');
|
||||
}
|
||||
|
||||
ws.close();
|
||||
});
|
||||
|
||||
ws.on('error', function incoming(data) {
|
||||
console.error(data);
|
||||
ws.close();
|
||||
});
|
||||
|
||||
ws.on('close', function incoming(data) {
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
199
test/automated/api/configmanagement.test.js
Normal file
199
test/automated/api/configmanagement.test.js
Normal file
@@ -0,0 +1,199 @@
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
|
||||
const serverName = randomString();
|
||||
const streamTitle = randomString();
|
||||
const serverSummary = randomString();
|
||||
const pageContent = `<p>${randomString()}</p>`;
|
||||
const tags = [randomString(), randomString(), randomString()];
|
||||
const latencyLevel = Math.floor(Math.random() * 4);
|
||||
|
||||
const streamOutputVariants = {
|
||||
videoBitrate: randomNumber() * 100,
|
||||
framerate: 42,
|
||||
cpuUsageLevel: 2,
|
||||
scaledHeight: randomNumber() * 100,
|
||||
scaledWidth: randomNumber() * 100,
|
||||
};
|
||||
const socialHandles = [
|
||||
{
|
||||
url: 'http://facebook.org/' + randomString(),
|
||||
platform: randomString(),
|
||||
},
|
||||
];
|
||||
|
||||
const s3Config = {
|
||||
enabled: true,
|
||||
endpoint: 'http://' + randomString(),
|
||||
accessKey: randomString(),
|
||||
secret: randomString(),
|
||||
bucket: randomString(),
|
||||
region: randomString(),
|
||||
};
|
||||
|
||||
const forbiddenUsernames = [randomString(), randomString(), randomString()];
|
||||
|
||||
test('set server name', async (done) => {
|
||||
const res = await sendConfigChangeRequest('name', serverName);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set stream title', async (done) => {
|
||||
const res = await sendConfigChangeRequest('streamtitle', streamTitle);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set server summary', async (done) => {
|
||||
const res = await sendConfigChangeRequest('serversummary', serverSummary);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set extra page content', async (done) => {
|
||||
const res = await sendConfigChangeRequest('pagecontent', pageContent);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set tags', async (done) => {
|
||||
const res = await sendConfigChangeRequest('tags', tags);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set latency level', async (done) => {
|
||||
const res = await sendConfigChangeRequest(
|
||||
'video/streamlatencylevel',
|
||||
latencyLevel
|
||||
);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set video stream output variants', async (done) => {
|
||||
const res = await sendConfigChangeRequest('video/streamoutputvariants', [
|
||||
streamOutputVariants,
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set social handles', async (done) => {
|
||||
const res = await sendConfigChangeRequest('socialhandles', socialHandles);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set s3 configuration', async (done) => {
|
||||
const res = await sendConfigChangeRequest('s3', s3Config);
|
||||
done();
|
||||
});
|
||||
|
||||
test('set forbidden usernames', async (done) => {
|
||||
const res = await sendConfigChangeRequest('chat/forbiddenusernames', forbiddenUsernames);
|
||||
done();
|
||||
});
|
||||
|
||||
test('verify updated config values', async (done) => {
|
||||
const res = await request.get('/api/config');
|
||||
expect(res.body.name).toBe(serverName);
|
||||
expect(res.body.streamTitle).toBe(streamTitle);
|
||||
expect(res.body.summary).toBe(`<p>${serverSummary}</p>`);
|
||||
expect(res.body.extraPageContent).toBe(pageContent);
|
||||
expect(res.body.logo).toBe('/logo');
|
||||
expect(res.body.socialHandles).toStrictEqual(socialHandles);
|
||||
done();
|
||||
});
|
||||
|
||||
// Test that the raw video details being broadcasted are coming through
|
||||
test('stream details are correct', (done) => {
|
||||
request
|
||||
.get('/api/admin/status')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body.broadcaster.streamDetails.width).toBe(320);
|
||||
expect(res.body.broadcaster.streamDetails.height).toBe(180);
|
||||
expect(res.body.broadcaster.streamDetails.framerate).toBe(24);
|
||||
expect(res.body.broadcaster.streamDetails.videoBitrate).toBe(1269);
|
||||
expect(res.body.broadcaster.streamDetails.videoCodec).toBe('H.264');
|
||||
expect(res.body.broadcaster.streamDetails.audioCodec).toBe('AAC');
|
||||
expect(res.body.online).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('admin configuration is correct', (done) => {
|
||||
request
|
||||
.get('/api/admin/serverconfig')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body.instanceDetails.name).toBe(serverName);
|
||||
expect(res.body.instanceDetails.summary).toBe(serverSummary);
|
||||
expect(res.body.instanceDetails.tags).toStrictEqual(tags);
|
||||
expect(res.body.instanceDetails.socialHandles).toStrictEqual(
|
||||
socialHandles
|
||||
);
|
||||
expect(res.body.forbiddenUsernames).toStrictEqual(forbiddenUsernames);
|
||||
|
||||
expect(res.body.videoSettings.latencyLevel).toBe(latencyLevel);
|
||||
expect(res.body.videoSettings.videoQualityVariants[0].framerate).toBe(
|
||||
streamOutputVariants.framerate
|
||||
);
|
||||
expect(res.body.videoSettings.videoQualityVariants[0].cpuUsageLevel).toBe(
|
||||
streamOutputVariants.cpuUsageLevel
|
||||
);
|
||||
|
||||
expect(res.body.yp.enabled).toBe(false);
|
||||
expect(res.body.streamKey).toBe('abc123');
|
||||
|
||||
expect(res.body.s3.enabled).toBe(s3Config.enabled);
|
||||
expect(res.body.s3.endpoint).toBe(s3Config.endpoint);
|
||||
expect(res.body.s3.accessKey).toBe(s3Config.accessKey);
|
||||
expect(res.body.s3.secret).toBe(s3Config.secret);
|
||||
expect(res.body.s3.bucket).toBe(s3Config.bucket);
|
||||
expect(res.body.s3.region).toBe(s3Config.region);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('frontend configuration is correct', (done) => {
|
||||
request
|
||||
.get('/api/config')
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body.name).toBe(serverName);
|
||||
expect(res.body.logo).toBe('/logo');
|
||||
expect(res.body.socialHandles).toStrictEqual(socialHandles);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
async function sendConfigChangeRequest(endpoint, value) {
|
||||
const url = '/api/admin/config/' + endpoint;
|
||||
const res = await request
|
||||
.post(url)
|
||||
.auth('admin', 'abc123')
|
||||
.send({ value: value })
|
||||
.expect(200);
|
||||
|
||||
expect(res.body.success).toBe(true);
|
||||
return res;
|
||||
}
|
||||
|
||||
async function sendConfigChangePayload(endpoint, payload) {
|
||||
const url = '/api/admin/config/' + endpoint;
|
||||
const res = await request
|
||||
.post(url)
|
||||
.auth('admin', 'abc123')
|
||||
.send(payload)
|
||||
.expect(200);
|
||||
|
||||
expect(res.body.success).toBe(true);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function randomString(length = 20) {
|
||||
return Math.random().toString(16).substr(2, length);
|
||||
}
|
||||
|
||||
function randomNumber() {
|
||||
return Math.floor(Math.random() * 5);
|
||||
}
|
||||
10
test/automated/api/index.test.js
Normal file
10
test/automated/api/index.test.js
Normal file
@@ -0,0 +1,10 @@
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
|
||||
test('service is online', (done) => {
|
||||
request.get('/api/status').expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body.online).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
178
test/automated/api/integrations.test.js
Normal file
178
test/automated/api/integrations.test.js
Normal file
@@ -0,0 +1,178 @@
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
|
||||
var accessToken = '';
|
||||
var webhookID;
|
||||
|
||||
const webhook = 'https://super.duper.cool.thing.biz/owncast';
|
||||
const events = ['CHAT'];
|
||||
|
||||
test('create webhook', async (done) => {
|
||||
const res = await sendIntegrationsChangePayload('webhooks/create', {
|
||||
url: webhook,
|
||||
events: events,
|
||||
});
|
||||
|
||||
expect(res.body.url).toBe(webhook);
|
||||
expect(res.body.timestamp).toBeTruthy();
|
||||
expect(res.body.events).toStrictEqual(events);
|
||||
done();
|
||||
});
|
||||
|
||||
test('check webhooks', (done) => {
|
||||
request
|
||||
.get('/api/admin/webhooks')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body).toHaveLength(1);
|
||||
expect(res.body[0].url).toBe(webhook);
|
||||
expect(res.body[0].events).toStrictEqual(events);
|
||||
webhookID = res.body[0].id;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('delete webhook', async (done) => {
|
||||
const res = await sendIntegrationsChangePayload('webhooks/delete', {
|
||||
id: webhookID,
|
||||
});
|
||||
expect(res.body.success).toBe(true);
|
||||
done();
|
||||
});
|
||||
|
||||
test('check that webhook was deleted', (done) => {
|
||||
request
|
||||
.get('/api/admin/webhooks')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body).toHaveLength(0);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('create access token', async (done) => {
|
||||
const name = 'Automated integration test';
|
||||
const scopes = [
|
||||
'CAN_SEND_SYSTEM_MESSAGES',
|
||||
'CAN_SEND_MESSAGES',
|
||||
'HAS_ADMIN_ACCESS',
|
||||
];
|
||||
const res = await sendIntegrationsChangePayload('accesstokens/create', {
|
||||
name: name,
|
||||
scopes: scopes,
|
||||
});
|
||||
|
||||
expect(res.body.accessToken).toBeTruthy();
|
||||
expect(res.body.createdAt).toBeTruthy();
|
||||
expect(res.body.displayName).toBe(name);
|
||||
expect(res.body.scopes).toStrictEqual(scopes);
|
||||
accessToken = res.body.accessToken;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
test('check access tokens', async (done) => {
|
||||
const res = await request
|
||||
.get('/api/admin/accesstokens')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
const tokenCheck = res.body.filter(
|
||||
(token) => token.accessToken === accessToken
|
||||
);
|
||||
expect(tokenCheck).toHaveLength(1);
|
||||
done();
|
||||
});
|
||||
|
||||
test('send a system message using access token', async (done) => {
|
||||
const payload = {
|
||||
body: 'This is a test system message from the automated integration test',
|
||||
};
|
||||
const res = await request
|
||||
.post('/api/integrations/chat/system')
|
||||
.set('Authorization', 'Bearer ' + accessToken)
|
||||
.send(payload)
|
||||
.expect(200);
|
||||
done();
|
||||
});
|
||||
|
||||
test('send an external integration message using access token', async (done) => {
|
||||
const payload = {
|
||||
body: 'This is a test external message from the automated integration test',
|
||||
};
|
||||
const res = await request
|
||||
.post('/api/integrations/chat/send')
|
||||
.set('Authorization', 'Bearer ' + accessToken)
|
||||
.send(payload)
|
||||
.expect(200);
|
||||
done();
|
||||
});
|
||||
|
||||
test('send an external integration action using access token', async (done) => {
|
||||
const payload = {
|
||||
body: 'This is a test external action from the automated integration test',
|
||||
};
|
||||
const res = await request
|
||||
.post('/api/integrations/chat/action')
|
||||
.set('Authorization', 'Bearer ' + accessToken)
|
||||
.send(payload)
|
||||
.expect(200);
|
||||
done();
|
||||
});
|
||||
|
||||
test('test fetch chat history using access token', async (done) => {
|
||||
const res = await request
|
||||
.get('/api/integrations/chat')
|
||||
.set('Authorization', 'Bearer ' + accessToken)
|
||||
.expect(200);
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
test('test fetch chat history failure using invalid access token', async (done) => {
|
||||
const res = await request
|
||||
.get('/api/integrations/chat')
|
||||
.set('Authorization', 'Bearer ' + 'invalidToken')
|
||||
.expect(401);
|
||||
done();
|
||||
});
|
||||
|
||||
test('test fetch chat history OPTIONS request', async (done) => {
|
||||
const res = await request
|
||||
.options('/api/integrations/chat')
|
||||
.set('Authorization', 'Bearer ' + accessToken)
|
||||
.expect(204);
|
||||
done();
|
||||
});
|
||||
|
||||
test('delete access token', async (done) => {
|
||||
const res = await sendIntegrationsChangePayload('accesstokens/delete', {
|
||||
token: accessToken,
|
||||
});
|
||||
expect(res.body.success).toBe(true);
|
||||
done();
|
||||
});
|
||||
|
||||
test('check token delete was successful', async (done) => {
|
||||
const res = await request
|
||||
.get('/api/admin/accesstokens')
|
||||
.auth('admin', 'abc123')
|
||||
.expect(200);
|
||||
const tokenCheck = res.body.filter(
|
||||
(token) => token.accessToken === accessToken
|
||||
);
|
||||
expect(tokenCheck).toHaveLength(0);
|
||||
done();
|
||||
});
|
||||
|
||||
async function sendIntegrationsChangePayload(endpoint, payload) {
|
||||
const url = '/api/admin/' + endpoint;
|
||||
const res = await request
|
||||
.post(url)
|
||||
.auth('admin', 'abc123')
|
||||
.send(payload)
|
||||
.expect(200);
|
||||
|
||||
return res;
|
||||
}
|
||||
33
test/automated/api/lib/chat.js
Normal file
33
test/automated/api/lib/chat.js
Normal file
@@ -0,0 +1,33 @@
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
const WebSocket = require('ws');
|
||||
|
||||
async function registerChat() {
|
||||
try {
|
||||
const response = await request.post('/api/chat/register');
|
||||
return response.body;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
function sendChatMessage(message, accessToken, done) {
|
||||
const ws = new WebSocket(
|
||||
`ws://localhost:8080/ws?accessToken=${accessToken}`,
|
||||
{
|
||||
origin: 'http://localhost:8080',
|
||||
}
|
||||
);
|
||||
|
||||
function onOpen() {
|
||||
ws.send(JSON.stringify(message), function () {
|
||||
ws.close();
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
ws.on('open', onOpen);
|
||||
}
|
||||
|
||||
module.exports.sendChatMessage = sendChatMessage;
|
||||
module.exports.registerChat = registerChat;
|
||||
11493
test/automated/api/package-lock.json
generated
Normal file
11493
test/automated/api/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
test/automated/api/package.json
Normal file
18
test/automated/api/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "owncast-test-automation",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "jest"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"supertest": "^6.0.1",
|
||||
"websocket": "^1.0.32"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jest": "^26.6.3"
|
||||
}
|
||||
}
|
||||
43
test/automated/api/run.sh
Executable file
43
test/automated/api/run.sh
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
TEMP_DB=$(mktemp)
|
||||
|
||||
# Install the node test framework
|
||||
npm install --silent > /dev/null
|
||||
|
||||
# Download a specific version of ffmpeg
|
||||
if [ ! -d "ffmpeg" ]; then
|
||||
mkdir ffmpeg
|
||||
pushd ffmpeg > /dev/null
|
||||
curl -sL https://github.com/vot/ffbinaries-prebuilt/releases/download/v4.2.1/ffmpeg-4.2.1-linux-64.zip --output ffmpeg.zip > /dev/null
|
||||
unzip -o ffmpeg.zip > /dev/null
|
||||
PATH=$PATH:$(pwd)
|
||||
popd > /dev/null
|
||||
fi
|
||||
|
||||
pushd ../../.. > /dev/null
|
||||
|
||||
# Build and run owncast from source
|
||||
go build -o owncast main.go pkged.go
|
||||
./owncast -database $TEMP_DB &
|
||||
SERVER_PID=$!
|
||||
|
||||
popd > /dev/null
|
||||
sleep 5
|
||||
|
||||
# Start streaming the test file over RTMP to
|
||||
# the local owncast instance.
|
||||
ffmpeg -hide_banner -loglevel panic -stream_loop -1 -re -i ../test.mp4 -vcodec libx264 -profile:v main -sc_threshold 0 -b:v 1300k -acodec copy -f flv rtmp://127.0.0.1/live/abc123 &
|
||||
FFMPEG_PID=$!
|
||||
|
||||
function finish {
|
||||
rm $TEMP_DB
|
||||
kill $SERVER_PID $FFMPEG_PID
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
echo "Waiting..."
|
||||
sleep 13
|
||||
|
||||
# Run the tests against the instance.
|
||||
npm test
|
||||
Reference in New Issue
Block a user