🐛 Update: Added support for the 'find' command in settings.local.json. Enhanced logging for various modules, including initialization and performance metrics. Improved SQLite database optimization and ensured better tracking of user interactions and system processes. 📚

This commit is contained in:
2025-06-14 16:26:43 +02:00
parent ee54bc273c
commit 89037861e3
2472 changed files with 691099 additions and 1 deletions

View File

@@ -0,0 +1,67 @@
var request = require('supertest');
var path = require('path');
var liveServer = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false
});
describe('basic functional tests', function(){
it('should respond with index.html', function(done){
request(liveServer)
.get('/')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/hello world/i)
.expect(200, done);
});
it('should have injected script', function(done){
request(liveServer)
.get('/')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/<script [^]+?live reload enabled[^]+?<\/script>/i)
.expect(200, done);
});
it('should inject script when tags are in CAPS', function(done){
request(liveServer)
.get('/index-caps.htm')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/<script [^]+?live reload enabled[^]+?<\/script>/i)
.expect(200, done);
});
it('should inject to <head> when no <body>', function(done){
request(liveServer)
.get('/index-head.html')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/<script [^]+?live reload enabled[^]+?<\/script>/i)
.expect(200, done);
});
it('should inject also svg files', function(done){
request(liveServer)
.get('/test.svg')
.expect('Content-Type', 'image/svg+xml')
.expect(function(res) {
if (res.body.toString().indexOf("Live reload enabled") == -1)
throw new Error("injected code not found");
})
.expect(200, done);
});
it('should not inject html fragments', function(done){
request(liveServer)
.get('/fragment.html')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(function(res) {
if (res.text.toString().indexOf("Live reload enabled") > -1)
throw new Error("injected code should not be found");
})
.expect(200, done);
});
xit('should have WebSocket connection', function(done){
done(); // todo
});
xit('should reload on page change', function(done){
done(); // todo
});
xit('should reload (without refreshing) on css change', function(done){
done(); // todo
});
});

View File

@@ -0,0 +1,65 @@
var assert = require('assert');
var path = require('path');
var exec = require('child_process').execFile;
var cmd = path.join(__dirname, "..", "live-server.js");
var opts = {
timeout: 2000,
maxBuffer: 1024
};
function exec_test(args, callback) {
if (process.platform === 'win32')
exec(process.execPath, [ cmd ].concat(args), opts, callback);
else
exec(cmd, args, opts, callback);
}
describe('command line usage', function() {
it('--version', function(done) {
exec_test([ "--version" ], function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("live-server") === 0, "version not found");
done();
});
});
it('--help', function(done) {
exec_test([ "--help" ], function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("Usage: live-server") === 0, "usage not found");
done();
});
});
it('--quiet', function(done) {
exec_test([ "--quiet", "--no-browser", "--test" ], function(error, stdout, stdin) {
assert(!error, error);
assert(stdout === "", "stdout not empty");
done();
});
});
it('--port', function(done) {
exec_test([ "--port=16123", "--no-browser", "--test" ], function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("Serving") >= 0, "serving string not found");
assert(stdout.indexOf("at http://127.0.0.1:16123") != -1, "port string not found");
done();
});
});
it('--host', function(done) {
exec_test([ "--host=localhost", "--no-browser", "--test" ], function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("Serving") >= 0, "serving string not found");
assert(stdout.indexOf("at http://localhost:") != -1, "host string not found");
done();
});
});
it('--htpasswd', function(done) {
exec_test(
[ "--htpasswd=" + path.join(__dirname, "data/htpasswd-test"),
"--no-browser",
"--test"
], function(error, stdout, stdin) {
assert(!error, error);
assert(stdout.indexOf("Serving") >= 0, "serving string not found");
done();
});
});
});

View File

@@ -0,0 +1,7 @@
var fs = require("fs");
module.exports = {
cert: fs.readFileSync(__dirname + "/server.cert"),
key: fs.readFileSync(__dirname + "/server.key"),
passphrase: "12345"
};

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDbzCCAlegAwIBAgIJAITs++EKEa1pMA0GCSqGSIb3DQEBCwUAME4xCzAJBgNV
BAYTAlVTMQ0wCwYDVQQIDAR0ZXN0MQ0wCwYDVQQHDAR0ZXN0MSEwHwYDVQQKDBhJ
bnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTYwNDIzMDgwMDM0WhcNMTYwNTIz
MDgwMDM0WjBOMQswCQYDVQQGEwJVUzENMAsGA1UECAwEdGVzdDENMAsGA1UEBwwE
dGVzdDEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkq
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnq4nI7HM0JITcpDrBPGBXl6ieVmsboKv
rTDJpLkDj+0kdDYMcdUhBuu4rpuUHnIZMHwPAYPx/uc5jr0OksAUqOmWXdZAgWUb
f7jBzaEQZb1CY8bbv/E/LlRSojPCJZYlQqcS3McGoSV01hPGMVNV3L3rVZGOKIdm
kpjbu/JppCLWpfA7OT/kUAjMnGSgOLMVpc76mUNeDG9ObhArrXImTjvUXntmUFbZ
W9mxgnRCJRK/ttWQp/KSlVJUxtXGCf1u+U9m5tl+/4LqRIfdTvy4NBxg/su3cdgq
Q/McAarhkgc1F141n7T9q7N8/nc2XsYWdMqLAn7NxIEJSUOmS8At/wIDAQABo1Aw
TjAdBgNVHQ4EFgQU+YZux6UXl7e9+rabdFH19GpcaNwwHwYDVR0jBBgwFoAU+YZu
x6UXl7e9+rabdFH19GpcaNwwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
AQEAQFL7tjp6NQjyoAmuaDyp7PXXVsGNKsN6zmGvdVrF9MVWhKnit0ByO/ytPxVX
ll+7RuKZqrhqm9HA1pStWbBI4P/mcYBqOyafb610DmGukM/++rdIBRQ9acGnIU0M
eg5finMBS4Rc2kmSz5tyHX+taX7J68Y3DUvBCC6VEb6ox+qJsQVVDEadeHjAr8wN
0SJK8/nKQBm7Tk0fEdBfUyyLdOz77i0+tmsJ8PIvPxYF1EVsgBDSz+6DS+Fjmps8
4/wfMM+ai+zBwf9H3bIu5XsHwbTEbLnYpFklwVeHM0sxEk/ZlSEMA9mtXBXaQOWd
yIo6uIKHbMrjbUmj3p65MFhaGQ==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,30 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIHqsvOM36+5UCAggA
MBQGCCqGSIb3DQMHBAgWDDD0SuRyYQSCBMifpjUCkt5NQYPATyi337ouCzeGt/Lw
jhgIUq8UelCGoQFz9omzOfm8XQmkhcwDRl1PX50HTdPeeRuEGs00/6ZjigakHQ+/
CIFhEo9WzjsrZZbUU+wMF1o5eelEmo3bIjUb55VNi60c0Mb8KUE8jnNlZmbcQEjL
wGpqph5moE/EFUmBTIza78XH51BpiSRo2/1mICAbR8k613mQc6eRaTJroleYulnE
+7wEVRTdW9dzt5oWcdK23g+1ayg00Rg9CRDQS85BvyrcSCBvp5HirV3VQWgdgPY/
9AFEogE1uyODp6yHW0RWoj0ycpafJVsQvGkI4tOu+gy38LI2gr4gA2fUEpcyZXiw
eTfQzlSKbsL9Dr1xHFe1o4S/NyFYKW/FJFUkJaskpHTkYBTWeqfqQnOVBv70juyQ
fGKnKaEX+AZj0Huj0bda1Uui8qnkkL3JkZ+AxhlXFkolVuUccIinTvwr3BuxpcBH
6T1hSpnjBf/QAMg5vO165k5dE6JOJb3zQ9byK2md6VDUpwHbubtEa4FdLxOa/6q1
SB/UABnPpyN2c0a1/UxF/PDDe6+Fb2rIIBYx5tB7dATFr6ZhFDh7c77jzZ80g06Z
lOYhV2nB8IT1/mTkq8Apxkw2/aB6W0FIPxTNIGfUsA2be6AFb0a0TiM9XqzTpTNL
6CufCeNUnplf8rbwMsaDU3V3hnPwlStkdLl+7+ipY9FOA7kbTQdBJX8/GWgByZKw
U9AKAGXcNfHKaCpOT83q1XaYQ8Vj1tlC/wSXA8/3ZvX7kRZr5K+iLxUV5UfSA1h0
9C4UUx4rwliWITMFdCTGn1jZbokQo/HX2cF5C5Q2VFtuFz099MykmRgOgcZbFSAo
ioRWfuMyQvhuzEchr08n0WU1FQOrHc/jjHjCKQECQjHAcvHDUwr+Bcbym6n7jSIQ
8NySJcfPS/F5PxSlisuzJzwWJxx3Nqv/KWfMR0wJuKYLyn5P7a6wAg7BZmxmb4TH
0OmaIzeNuy0qMF774fESXTLrk3i9AffXAbIuHTKiYp+QKfIOjLZ4vTr3iZdaOLNw
SSdsLwBgPH8st1MWR+qnk4ry44DE72hW5/uELmfENq9IPc1vA4V88qCTXFNFlYvY
HBTmA7jiLTzyqAVgmXTv5fw7iQ3+1NLNBPNN45rFmWEQcQvqfvla7COxtREAWDh3
1apQJ1A5DIZir5Y2QNFUGgcX8T7tWsE2cWEUqwTGwUQq4ovwkf53+nqnuRJ7In7S
YFTXy2fCDCjuB7GsgGPa4cNH4L1ru85+CQtVOW7FjdmVvrm2cyvtzoYKb/BOLnNO
PVjWb7gTBxEqKv2LnxdTb+RwtSn7T3cjBTgXHqR97ZNru9CMKtRVlR6b+H/1pbyJ
2fd6AdWRDNAPmDkEY+jADANoiMqlfkQU1UsCkDZu/4EpB80u5OZmeOQitmQIDK0d
kl2Wwmat2jHQrL1sPnbLGMan8g8c3cU6bBqoiJcDlRKu0FMyHTqY4f297XJLi8v9
vk5j6F1buFnnJ3nXtPZBA5W03/G5CyXx6M65dUXV/3ZtukQYE6n68FvU9ADRCm/y
QxohXz60JhV8V9Gailc17ZiiZUXQ6SOfZ1NCHXjbLfDiHDwL3VADnpC2rB2xg7tX
GKQ=
-----END ENCRYPTED PRIVATE KEY-----

View File

@@ -0,0 +1,42 @@
var request = require('supertest');
var path = require('path');
var liveServer = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false,
cors: true
});
describe('cors tests', function() {
it('should respond with appropriate header', function(done) {
request(liveServer)
.get('/index.html')
.set('Origin', 'http://example.com')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect('Access-Control-Allow-Origin', 'http://example.com')
.expect(/Hello world/i)
.expect(200, done);
});
it('should support preflighted requests', function(done) {
request(liveServer)
.options('/index.html')
.set('Origin', 'http://example.com')
.set('Access-Control-Request-Method', 'POST')
.set('Access-Control-Request-Headers', 'X-PINGOTHER')
.expect('Access-Control-Allow-Origin', 'http://example.com')
.expect('Access-Control-Allow-Methods', /POST/)
.expect('Access-Control-Allow-Headers', 'X-PINGOTHER')
.expect(204, done);
});
it('should support requests with credentials', function(done) {
request(liveServer)
.options('/index.html')
.set('Origin', 'http://example.com')
.set('Cookie', 'foo=bar')
.expect('Access-Control-Allow-Origin', 'http://example.com')
.expect('Access-Control-Allow-Credentials', 'true')
.expect(204, done);
});
});

View File

@@ -0,0 +1,3 @@
<h1>
{{this imitates some kind of template fragment}}
</h1>

View File

@@ -0,0 +1 @@
test:$apr1$edJu7/51$LVD5BTHDtDMzzeeYnWXCL1

View File

@@ -0,0 +1,13 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<HTML lang="en">
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=utf-8" >
<TITLE>Live-server Test Page</TITLE>
<LINK rel="stylesheet" href="style.css" >
</HEAD>
<BODY>
<H1>Hello world.</H1>
<P>These tags are in capitals.</P>
</BODY>
</HTML>

View File

@@ -0,0 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Live-server Test Page</title>
<link rel="stylesheet" href="style.css" />
</head>
</html>

View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Live-server Test Page</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<h1>Hello world.</h1>
<p>Edit my css for a live-reload without refreshing.</p>
</body>
</html>

View File

@@ -0,0 +1,5 @@
module.exports = function(req, res, next) {
res.statusCode = 203;
next();
}

View File

@@ -0,0 +1 @@
h1 { color: red; }

View File

@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Live-server Test Page</title>
</head>
<body>
<h1>Subdirectory</h1>
</body>
</html>

View File

@@ -0,0 +1,14 @@
<svg width="100%" height="100%" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">
// <![CDATA[
function change(evt) {
var target = evt.target;
var radius = target.getAttribute("r");
radius = (radius == 15) ? 45 : 15
target.setAttribute("r", radius);
}
// ]]>
</script>
<circle cx="50" cy="50" r="45" fill="green" onclick="change(evt)" />
</svg>

After

Width:  |  Height:  |  Size: 415 B

View File

@@ -0,0 +1,28 @@
var request = require('supertest');
var path = require('path');
var liveServer = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false,
htpasswd: path.join(__dirname, "data", "htpasswd-test")
});
describe('htpasswd tests', function() {
it('should respond with 401 since no password is given', function(done) {
request(liveServer)
.get('/')
.expect(401, done);
});
it('should respond with 401 since wrong password is given', function(done) {
request(liveServer)
.get('/')
.auth("test", "not-real-password")
.expect(401, done);
});
it('should respond with 200 since correct password is given', function(done) {
request(liveServer)
.get('/')
.auth("test", "test")
.expect(200, done);
});
});

View File

@@ -0,0 +1,48 @@
var request = require('supertest');
var path = require('path');
// accept self-signed certificates
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
function tests(liveServer) {
it('should reply with a correct index file', function(done) {
request(liveServer)
.get('/index.html')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/Hello world/i)
.expect(200, done);
});
it('should support head request', function(done) {
request(liveServer)
.head('/index.html')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(200, done);
});
}
describe('https tests with external module', function() {
var opts = {
root: path.join(__dirname, 'data'),
port: 0,
open: false,
https: path.join(__dirname, 'conf/https.conf.js')
};
var liveServer = require("..").start(opts);
tests(liveServer);
after(function () {
liveServer.close()
});
});
describe('https tests with object', function() {
var opts = {
root: path.join(__dirname, 'data'),
port: 0,
open: false,
https: require(path.join(__dirname, 'conf/https.conf.js'))
};
var liveServer = require("..").start(opts);
tests(liveServer);
after(function () {
liveServer.close()
});
});

View File

@@ -0,0 +1,43 @@
var request = require('supertest');
var path = require('path');
var liveServer1 = require('..').start({
root: path.join(__dirname, 'data'),
port: 0,
open: false,
middleware: [
function setStatus(req, res, next) {
res.statusCode = 201;
next();
}
]
});
var liveServer2 = require('..').start({
root: path.join(__dirname, 'data'),
port: 0,
open: false,
middleware: [ "example" ]
});
var liveServer3 = require('..').start({
root: path.join(__dirname, 'data'),
port: 0,
open: false,
middleware: [ path.join(__dirname, 'data', 'middleware.js') ]
});
describe('middleware tests', function() {
it("should respond with middleware function's status code", function(done) {
request(liveServer1)
.get('/')
.expect(201, done);
});
it("should respond with built-in middleware's status code", function(done) {
request(liveServer2)
.get('/')
.expect(202, done);
});
it("should respond with external middleware's status code", function(done) {
request(liveServer3)
.get('/')
.expect(203, done);
});
});

View File

@@ -0,0 +1,30 @@
var request = require('supertest');
var path = require('path');
var liveServer = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false,
mount: [
[ "/mounted", path.join(__dirname, "data", "sub") ],
[ "/style", path.join(__dirname, "data", "style.css") ]
]
});
describe('mount tests', function() {
it('should respond with sub.html', function(done) {
request(liveServer)
.get('/mounted/sub.html')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/Subdirectory/i)
.expect(200, done);
});
it('should respond with style.css', function(done) {
request(liveServer)
.get('/style')
.expect('Content-Type', 'text/css; charset=UTF-8')
.expect(/color/i)
.expect(200, done);
});
});

View File

@@ -0,0 +1,28 @@
var request = require('supertest');
var path = require('path');
var port = 40200;
var server1 = require('..').start({
root: path.join(__dirname, "data"),
port: port,
open: false
});
var server2 = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false,
proxy: [
["/server1", "http://localhost:" + port]
]
});
describe('proxy tests', function() {
it('should respond with proxied content', function(done) {
request(server2)
.get('/server1/index.html')
.expect('Content-Type', 'text/html; charset=UTF-8')
.expect(/Hello world/i)
.expect(200, done);
});
});

View File

@@ -0,0 +1,40 @@
var request = require('supertest');
var path = require('path');
var liveServerSpa = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false,
middleware: [ "spa" ]
});
var liveServerSpaIgnoreAssets = require('..').start({
root: path.join(__dirname, "data"),
port: 0,
open: false,
middleware: [ "spa-ignore-assets" ]
});
describe('spa tests', function(){
it('spa should redirect', function(done){
request(liveServerSpa)
.get('/api')
.expect('Location', /\/#\//)
.expect(302, done);
});
it('spa should redirect everything', function(done){
request(liveServerSpa)
.get('/style.css')
.expect('Location', /\/#\//)
.expect(302, done);
});
it('spa-ignore-assets should redirect something', function(done){
request(liveServerSpaIgnoreAssets)
.get('/api')
.expect('Location', /\/#\//)
.expect(302, done);
});
it('spa-ignore-assets should not redirect .css', function(done){
request(liveServerSpaIgnoreAssets)
.get('/style.css')
.expect(200, done);
});
});