End to end automated tests run on Github workflows (#384)
* WIP for automated integration test * See if it runs under a workflow * Support running test locally as well as a workflow * Use already downloaded repo to build. Do not re-clone * Add comments * Update to support new default config file * Split out different test suites * Add test for chat * Always run test with config-default and ignore local config file * Remove the build workflow because the end to end test does that now
This commit is contained in:
2
test/automated/.gitignore
vendored
Normal file
2
test/automated/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
ffmpeg
|
||||
49
test/automated/admin.test.js
Normal file
49
test/automated/admin.test.js
Normal file
@@ -0,0 +1,49 @@
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
|
||||
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('Owncast');
|
||||
expect(res.body.instanceDetails.title).toBe('Owncast');
|
||||
expect(res.body.instanceDetails.summary).toBe('This is brief summary of whom you are or what your stream is. You can edit this description in your config file.');
|
||||
expect(res.body.instanceDetails.logo).toBe('/img/logo.svg');
|
||||
expect(res.body.instanceDetails.tags).toStrictEqual(['music', 'software', 'streaming']);
|
||||
|
||||
expect(res.body.videoSettings.segmentLengthSeconds).toBe(4);
|
||||
expect(res.body.videoSettings.numberOfPlaylistItems).toBe(5);
|
||||
|
||||
expect(res.body.videoSettings.videoQualityVariants[0].framerate).toBe(24);
|
||||
expect(res.body.videoSettings.videoQualityVariants[0].encoderPreset).toBe('veryfast');
|
||||
|
||||
expect(res.body.videoSettings.numberOfPlaylistItems).toBe(5);
|
||||
|
||||
expect(res.body.yp.enabled).toBe(false);
|
||||
expect(res.body.streamKey).toBe('abc123');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('correct number of log entries exist', (done) => {
|
||||
request.get('/api/admin/logs').auth('admin', 'abc123').expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body).toHaveLength(4);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
49
test/automated/chat.test.js
Normal file
49
test/automated/chat.test.js
Normal file
@@ -0,0 +1,49 @@
|
||||
const { test } = require('@jest/globals');
|
||||
var request = require('supertest');
|
||||
request = request('http://127.0.0.1:8080');
|
||||
|
||||
const WebSocket = require('ws');
|
||||
var ws;
|
||||
|
||||
const id = Math.random().toString(36).substring(7);
|
||||
const username = 'user' + Math.floor(Math.random() * 100);
|
||||
const message = Math.floor(Math.random() * 100) + ' test 123';
|
||||
const messageRaw = message + ' *and some markdown too*';
|
||||
const messageMarkdown = '<p>' + message + ' <em>and some markdown too</em></p>'
|
||||
const date = new Date().toISOString();
|
||||
|
||||
const testMessage = {
|
||||
author: username,
|
||||
body: messageRaw,
|
||||
id: id,
|
||||
type: 'CHAT',
|
||||
visible: true,
|
||||
timestamp: date,
|
||||
};
|
||||
|
||||
test('can send a chat message', (done) => {
|
||||
ws = new WebSocket('ws://127.0.0.1:8080/entry', {
|
||||
origin: 'http://localhost',
|
||||
});
|
||||
|
||||
function onOpen() {
|
||||
ws.send(JSON.stringify(testMessage), function() {
|
||||
ws.close();
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
ws.on('open', onOpen);
|
||||
});
|
||||
|
||||
test('can fetch chat messages', (done) => {
|
||||
request.get('/api/chat').expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body[0].author).toBe(testMessage.author);
|
||||
expect(res.body[0].body).toBe(messageMarkdown);
|
||||
expect(res.body[0].date).toBe(testMessage.date);
|
||||
expect(res.body[0].type).toBe(testMessage.type);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
21
test/automated/index.test.js
Normal file
21
test/automated/index.test.js
Normal file
@@ -0,0 +1,21 @@
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
test('frontend configuration is correct', (done) => {
|
||||
request.get('/api/config').expect(200)
|
||||
.then((res) => {
|
||||
expect(res.body.title).toBe('Owncast');
|
||||
expect(res.body.logo).toBe('/img/logo.svg');
|
||||
expect(res.body.socialHandles[0].platform).toBe('github');
|
||||
expect(res.body.socialHandles[0].url).toBe('http://github.com/owncast/owncast');
|
||||
done();
|
||||
});
|
||||
});
|
||||
5197
test/automated/package-lock.json
generated
Normal file
5197
test/automated/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
test/automated/package.json
Normal file
18
test/automated/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/run.sh
Executable file
43
test/automated/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 -configFile config-default.yaml &
|
||||
SERVER_PID=$!
|
||||
|
||||
popd > /dev/null
|
||||
sleep 5
|
||||
|
||||
# Start streaming the test file over RTMP to
|
||||
# the local owncast instance.
|
||||
ffmpeg -hide_banner -loglevel panic -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 15
|
||||
|
||||
# Run the tests against the instance.
|
||||
npm test
|
||||
BIN
test/automated/test.mp4
Normal file
BIN
test/automated/test.mp4
Normal file
Binary file not shown.
Reference in New Issue
Block a user