Skip to content

Commit

Permalink
Added e2e test for websockets
Browse files Browse the repository at this point in the history
  • Loading branch information
rthenhaus committed Oct 10, 2024
1 parent 62a29d9 commit 7da6d17
Show file tree
Hide file tree
Showing 22 changed files with 299 additions and 170 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
/logs/*
/.git/*
npm-debug.log
DS_store
.DS_store
cypress
tsconfig.tsbuildinfo
.rollup.cache
Expand Down
3 changes: 0 additions & 3 deletions build/UserALEWebExtension/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -1215,9 +1215,6 @@ function setup(config) {
* and updates the config accordingly
*/
function getWebsocketsEnabled(config) {
if (!window.browser) {
return;
}
wsock = new WebSocket(config.url.replace("http://", "ws://"));
wsock.onerror = () => {
console.log("no websockets detected");
Expand Down
3 changes: 0 additions & 3 deletions build/UserALEWebExtension/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -1162,9 +1162,6 @@ function setup(config) {
* and updates the config accordingly
*/
function getWebsocketsEnabled(config) {
if (!window.browser) {
return;
}
wsock = new WebSocket(config.url.replace("http://", "ws://"));
wsock.onerror = () => {
console.log("no websockets detected");
Expand Down
3 changes: 0 additions & 3 deletions build/UserALEWebExtension/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -1162,9 +1162,6 @@ function setup(config) {
* and updates the config accordingly
*/
function getWebsocketsEnabled(config) {
if (!window.browser) {
return;
}
wsock = new WebSocket(config.url.replace("http://", "ws://"));
wsock.onerror = () => {
console.log("no websockets detected");
Expand Down
3 changes: 0 additions & 3 deletions build/userale-2.4.0.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion build/userale-2.4.0.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/userale-2.4.0.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,4 @@
<p>Click on the Link to Test Logging with Page Navigation</p>
<a href="http://flagon.incubator.apache.org/"><button id="Linked Button">Link to Flagon Page</button></a>
</body>
</html>
</html>
162 changes: 117 additions & 45 deletions example/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,27 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const express = require('express');
const bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
const express = require("express");
const w = require("ws");
const bodyParser = require("body-parser");
const fs = require("fs");
const path = require("path");

const logDirectory = path.resolve(__dirname, '../logs');
const logPath = path.resolve(logDirectory, 'logs_' + (new Date()).getTime() + '.json');
const logDirectory = path.resolve(__dirname, "../logs");
const logPath = path.resolve(
logDirectory,
"logs_" + new Date().getTime() + ".json",
);

try {
fs.lstatSync(logDirectory);
Expand All @@ -30,65 +34,128 @@ try {
}

const wStream = fs.createWriteStream(logPath);
wStream.on('open', function () {
wStream.write('[');
wStream.on("open", function () {
wStream.write("[");
});

let firstLog = true;

// ~~~~~~~~ Websocket Server ~~~~~~~~~~~~~~~~
const wss = new w.WebSocketServer({ port: 8001 });
wss.on("connection", (ws) => {
console.log("New client connected");

ws.on("message", (message) => {
console.log("message type:" + typeof message);
const body =
typeof message === "string"
? JSON.parse(message)
: JSON.parse(message.toString());

const isEmptyArray = Array.isArray(body) && body.length === 0;
const isEmptyObject =
typeof body === "object" &&
body !== null &&
Object.keys(body).length === 0;
if (isEmptyArray || isEmptyObject) return;

console.log(body);

let delimeter = ",\n\t";

if (firstLog) {
wStream.write("\n\t");
firstLog = false;
} else {
wStream.write(delimeter);
}

const logLength = message.length - 1;
body.forEach(function (log, i) {
if (i === logLength) {
delimeter = "";
}

wStream.write(JSON.stringify(log) + delimeter);
});
});

ws.on("close", () => {
console.log("Client disconnected");
});
});

console.log("UserAle Websocket server running on port 8001");
// ~~~~~~~ End Websocket Server ~~~~~~~~~~~~~~

// ~~~~~~~ Normal Server ~~~~~~~~~~~~~~~~~~~
const app = express();

app.set('port', process.env.PORT || 8000);
app.set("port", process.env.PORT || 8000);
app.use(function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
res.header(
"Access-Control-Allow-Headers",
"Content-Type, Authorization, Content-Length, X-Requested-With",
);

// intercept OPTIONS method
if ('OPTIONS' == req.method) {
if ("OPTIONS" == req.method) {
res.sendStatus(200);
}
else {
} else {
next();
}
});
app.use(bodyParser.urlencoded({extended: true, limit: '100mb'}));
app.use(bodyParser.json({limit: '100mb'}));
app.use(bodyParser.text())
app.use('/build', express.static(path.join(__dirname, '/../build')));
app.use('/', express.static(__dirname));
app.set('view engine', 'jade');
app.use('/', express.static(__dirname));

app.get('/', function (req, res) {
res.sendFile('index.html', { root: __dirname });
app.use(bodyParser.urlencoded({ extended: true, limit: "100mb" }));
app.use(bodyParser.json({ limit: "100mb" }));
app.use(bodyParser.text());
app.use("/build", express.static(path.join(__dirname, "/../build")));
app.use("/", express.static(__dirname));
app.set("view engine", "jade");
app.use("/", express.static(__dirname));

app.get("/", function (req, res) {
res.sendFile("index.html", { root: __dirname });
});

app.get("/ws", function (req, res) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
res.header(
"Access-Control-Allow-Headers",
"Content-Type, Authorization, Content-Length, X-Requested-With",
);
res.sendFile("ws-index.html", { root: __dirname });
});

app.get('/no-logging', function (req, res) {
res.sendFile('no-logging.html', { root: __dirname });
app.get("/no-logging", function (req, res) {
res.sendFile("no-logging.html", { root: __dirname });
});

app.post('/', function (req, res) {
const body = typeof req.body === "string" ? JSON.parse(req.body) : req.body
app.post("/", function (req, res) {
const body = typeof req.body === "string" ? JSON.parse(req.body) : req.body;

const isEmptyArray = (Array.isArray(body) && body.length === 0);
const isEmptyObject = (typeof body === 'object' && body !== null && Object.keys(body).length === 0);
if (isEmptyArray || isEmptyObject) return
const isEmptyArray = Array.isArray(body) && body.length === 0;
const isEmptyObject =
typeof body === "object" && body !== null && Object.keys(body).length === 0;
if (isEmptyArray || isEmptyObject) return;

console.log(body)
console.log(body);

let delimiter = ',\n\t';
let delimiter = ",\n\t";

if (firstLog) {
wStream.write('\n\t');
wStream.write("\n\t");
firstLog = false;
} else {
wStream.write(delimiter);
}

const logLength = req.body.length - 1;
body.forEach(function (log, i) {
if (i === logLength) {
delimiter = '';
delimiter = "";
}

wStream.write(JSON.stringify(log) + delimiter);
Expand All @@ -97,14 +164,19 @@ app.post('/', function (req, res) {
res.sendStatus(200);
});

app.listen(app.get('port'), function () {
console.log('UserAle Local running on port', app.get('port'));
app.listen(app.get("port"), function () {
console.log("UserAle Local running on port", app.get("port"));
});

function closeLogServer () {
wStream.end('\n]');
function closeLogServer() {
wStream.end("\n]");
process.exit();
}
// ~~~~~~~ End Normal Server ~~~~~~~~~~~~~

process.on('SIGTERM', function () { closeLogServer(); });
process.on('SIGINT', function () { closeLogServer(); });
process.on("SIGTERM", function () {
closeLogServer();
});
process.on("SIGINT", function () {
closeLogServer();
});
92 changes: 92 additions & 0 deletions example/ws-index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
<title>UserALE - Example Page</title>

<!-- Load UserALE and set logging parameters-->
<script
src="../build/userale-2.4.0.min.js"
data-url="http://localhost:8001/"
data-user="example-user"
data-log-details="true"
data-version="2.3.0"
data-tool="Apache UserALE Example"
data-threshold="1"
data-interval="1000"
></script>
<!-- Load UserALE API calls to modify log stream-->
<script
src="./index.js"
></script>
</head>
<body>
<br>
<p>
This UserALE Example Page lets you explore how UserALE works, deploys with a script tag, and the data it generates.<br>
By default, you'll see the raw logs UserALE generates. We kept this page simple so that its easy to see how things work.
</p>
<p>
To see how our API can be used to shape UserALE logs to your needs, uncomment the 'index.js' script tag in index.html.
</p>
<br>
<p>Click the button below to generate targeted click events.</p>
<div class="container">
<button id="test_button">Click Me!</button>
</div>
<br>
<br>
<p>Play around with the form elements below to see a variety of UserALE log types:</p>
<p>
Capture changes to fields (and values, when it's safe).
</p>
<p>
With index.js injected into the page, you can use the 'Test Field' below to see the behavior of our API dynamically.<br>
Type in the following UserALE function names to see their behavior.
<ul>
<li>"log" - ship a fully customized log, built from scratch</li>
<li>"packageLog" - hijack our own pipeline to modify and ship logs packaged exactly like standard UserALE logs</li>
<li>"packageCustomLog" - smash a number of custom fields together with UserALE standard metadata</li>
</ul>

<form id="test_text_input">
<label>Test Field: <input type="text"></label>
<br><br>
<button type="submit">Submit form</button>
</form>
<br>
<p>Capture inputs and changes to different types of selections.</p>
<select name="UserALE Committers">
<option value="clay">Clay</option>
<option value="rob">Rob</option>
<option value="michelle">Michelle</option>
<option value="josh">Josh</option>
</select>
<br>
<br>
<form id="test_radio_input">
<input type="radio" name="Use Case" value="business analytics" checked> Business Analytics<br>
<input type="radio" name="Use Case" value="HCI"> HCI<br>
<input type="radio" name="Use Case" value="other"> Other
</form>
<br>
<div class="container">
<button id="NonLink Button"> Don't Click Me!</button>
</div>
<br>
<p>Click on the Link to Test Logging with Page Navigation</p>
<a href="http://flagon.incubator.apache.org/"><button id="Linked Button">Link to Flagon Page</button></a>
</body>
</html>
Loading

0 comments on commit 7da6d17

Please sign in to comment.