mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Travis: add scripts to test if headless Chrome runs properly
This commit is contained in:
parent
492fd004af
commit
0a5ed2b4a5
|
@ -39,6 +39,11 @@ install:
|
|||
- npm config set prefix=$HOME/.node_modules
|
||||
- npm install
|
||||
- npm run build
|
||||
- google-chrome-stable --headless --disable-gpu --remote-debugging-port=9222 index.html &
|
||||
- BROWSER_PID=$!
|
||||
- node start.js test
|
||||
- node ./bin/test-chrome.js
|
||||
- kill $BROWSER_PID
|
||||
- popd
|
||||
- rm -rf tools/idea/idea-artifacts/dependencies
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ function tryConnect() {
|
|||
let ws = new WebSocket("ws://localhost:9090");
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log("Connected established");
|
||||
console.log("Connection established");
|
||||
listen(ws);
|
||||
};
|
||||
|
||||
|
@ -30,6 +30,10 @@ function tryConnect() {
|
|||
tryConnect();
|
||||
}, 500);
|
||||
};
|
||||
|
||||
ws.onerror = err => {
|
||||
console.log("Could not connect WebSocket", err);
|
||||
}
|
||||
}
|
||||
|
||||
function listen(ws) {
|
||||
|
@ -58,12 +62,14 @@ function runTests(ws, suiteId, tests, index) {
|
|||
|
||||
function runSingleTest(test, callback) {
|
||||
console.log("Running test " + test.name + " consisting of " + test.files);
|
||||
let iframe = document.getElementById("test");
|
||||
let iframe = document.createElement("iframe");
|
||||
document.body.appendChild(iframe);
|
||||
let handshakeListener = () => {
|
||||
window.removeEventListener("message", handshakeListener);
|
||||
|
||||
let listener = event => {
|
||||
window.removeEventListener("message", listener);
|
||||
document.body.removeChild(iframe);
|
||||
callback(event.data);
|
||||
};
|
||||
window.addEventListener("message", listener);
|
||||
|
|
|
@ -21,6 +21,5 @@
|
|||
<script src="client.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<iframe id="test" src="frame.html"></iframe>
|
||||
</body>
|
||||
</html>
|
118
tests/src/test/js/src/cdp.js
Normal file
118
tests/src/test/js/src/cdp.js
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright 2019 Alexey Andreev.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
import * as http from "http";
|
||||
import { client as WebSocketClient } from "websocket";
|
||||
|
||||
function httpGetJson(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
http.request(url, resp => {
|
||||
if (resp.statusCode !== 200) {
|
||||
reject(new Error(`HTTP status: ${resp.statusCode}`));
|
||||
return;
|
||||
}
|
||||
let data = "";
|
||||
resp.on('data', (chunk) => {
|
||||
data += chunk;
|
||||
});
|
||||
resp.on('end', () => {
|
||||
resolve(JSON.parse(data));
|
||||
});
|
||||
}).on("error", err => {
|
||||
reject(new Error(`HTTP error: ${err.message}`));
|
||||
}).end();
|
||||
});
|
||||
}
|
||||
|
||||
function connectWs(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const client = new WebSocketClient();
|
||||
client.on("connectFailed", error => reject(new Error('Connect Error: ' + error)));
|
||||
client.on("connect", resolve);
|
||||
client.connect(url);
|
||||
});
|
||||
}
|
||||
|
||||
class CDP {
|
||||
constructor(conn) {
|
||||
this.idGenerator = 1;
|
||||
this.pendingCalls = Object.create(null);
|
||||
this.eventHandlers = Object.create(null);
|
||||
this.conn = conn;
|
||||
}
|
||||
|
||||
start() {
|
||||
this.conn.on("message", message => {
|
||||
if (message.type === 'utf8') {
|
||||
const messageObj = JSON.parse(message.utf8Data);
|
||||
if (messageObj.id !== void 0) {
|
||||
const pendingCall = this.pendingCalls[messageObj.id];
|
||||
delete this.pendingCalls[messageObj.id];
|
||||
if (messageObj.error) {
|
||||
pendingCall.reject(new Error(`Error calling CDP method ${messageObj.error}`));
|
||||
} else {
|
||||
pendingCall.resolve(messageObj.result);
|
||||
}
|
||||
} else {
|
||||
const handlers = this.eventHandlers[messageObj.method];
|
||||
if (handlers) {
|
||||
for (const handler of handlers) {
|
||||
handler(messageObj.params);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
this.conn.on("close", () => {
|
||||
for (const key in Object.getOwnPropertyNames(this.pendingCalls)) {
|
||||
this.pendingCalls[key].reject(new Error("Connection closed before result received"));
|
||||
}
|
||||
});
|
||||
this.conn.on("error", err => {
|
||||
console.error("WS error: %j", err);
|
||||
});
|
||||
}
|
||||
|
||||
call(method, params = undefined) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const id = this.idGenerator++;
|
||||
this.pendingCalls[id] = { resolve, reject };
|
||||
this.conn.send(JSON.stringify({ id, method, params }));
|
||||
});
|
||||
}
|
||||
|
||||
async on(eventName, handler) {
|
||||
let handlers = this.eventHandlers[eventName];
|
||||
if (handlers === void 0) {
|
||||
handlers = [];
|
||||
this.eventHandlers[eventName] = handlers;
|
||||
}
|
||||
handlers.push(handler);
|
||||
}
|
||||
|
||||
static async connect(url) {
|
||||
const targets = await httpGetJson(url + "/json/list");
|
||||
const wsUrl = targets.find(target => target.type === "page").webSocketDebuggerUrl;
|
||||
console.log("Connected to Chrome");
|
||||
const wsConn = await connectWs(wsUrl);
|
||||
console.log(`Connected to WS endpoint: ${wsUrl}`);
|
||||
return wsConn;
|
||||
}
|
||||
}
|
||||
|
||||
export { CDP };
|
48
tests/src/test/js/src/log-chrome.js
Normal file
48
tests/src/test/js/src/log-chrome.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2019 Alexey Andreev.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { CDP } from "./cdp.js";
|
||||
|
||||
async function run() {
|
||||
const wsConn = await CDP.connect("http://localhost:9222");
|
||||
const cdp = new CDP(wsConn);
|
||||
const waitForLog = new Promise(resolve => {
|
||||
let timeout = setTimeout(resolve, 500);
|
||||
cdp.on("Runtime.consoleAPICalled", event => {
|
||||
const value = event.args.filter(arg => arg.type === "string").map(arg => arg.value).join("");
|
||||
if (value !== "") {
|
||||
console.log("[LOG] " + new Date(event.timestamp) + ": " + value);
|
||||
}
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(resolve, 500);
|
||||
});
|
||||
});
|
||||
|
||||
cdp.start();
|
||||
|
||||
try {
|
||||
await cdp.call("Runtime.enable");
|
||||
await waitForLog;
|
||||
} finally {
|
||||
wsConn.close();
|
||||
}
|
||||
}
|
||||
|
||||
run().catch(e => {
|
||||
console.error("Error", e);
|
||||
});
|
|
@ -192,7 +192,7 @@ class TestRunner {
|
|||
|
||||
const resultPromises = [];
|
||||
|
||||
this.timeout = createRefreshableTimeoutPromise(10000);
|
||||
this.timeout = createRefreshableTimeoutPromise(20000);
|
||||
for (let i = 0; i < suite.testCases.length; ++i) {
|
||||
resultPromises.push(new Promise(resolve => {
|
||||
this.pendingRequests[request.id + "-" + i] = resolve;
|
||||
|
|
95
tests/src/test/js/src/test-chrome.js
Normal file
95
tests/src/test/js/src/test-chrome.js
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2019 Alexey Andreev.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
import { CDP } from "./cdp.js";
|
||||
|
||||
function waitForTest(cdp) {
|
||||
return new Promise(resolve => {
|
||||
let stage = 'initial';
|
||||
let requestId = null;
|
||||
cdp.on("Runtime.consoleAPICalled", event => {
|
||||
const value = event.args.filter(arg => arg.type === "string").map(arg => arg.value).join("");
|
||||
switch (stage) {
|
||||
case 'initial':
|
||||
if (value === 'Connection established') {
|
||||
stage = 'connected';
|
||||
}
|
||||
break;
|
||||
case 'connected': {
|
||||
const result = /Request #([0-9]+) received/.exec(value);
|
||||
if (result) {
|
||||
requestId = result[1];
|
||||
stage = 'sent';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'sent':
|
||||
if (value === "Running test only simple consisting of http://localhost:9090//only/test.js") {
|
||||
stage = 'ran';
|
||||
}
|
||||
break;
|
||||
case 'ran':
|
||||
if (value === "Sending response #" + requestId) {
|
||||
stage = 'received';
|
||||
resolve();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function timeout(time) {
|
||||
let timer;
|
||||
return {
|
||||
promise: new Promise((resolve, reject) => {
|
||||
timer = setTimeout(() => { reject(new Error("Timeout expired")); }, time);
|
||||
}),
|
||||
cancel: () => clearTimeout(timer)
|
||||
}
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const wsConn = await CDP.connect("http://localhost:9222");
|
||||
const cdp = new CDP(wsConn);
|
||||
cdp.on("Runtime.consoleAPICalled", event => {
|
||||
const value = event.args.filter(arg => arg.type === "string").map(arg => arg.value).join("");
|
||||
if (value !== "") {
|
||||
console.log("[LOG] " + new Date(event.timestamp) + ": " + value);
|
||||
}
|
||||
});
|
||||
|
||||
const wait = waitForTest(cdp);
|
||||
let timer;
|
||||
cdp.start();
|
||||
|
||||
try {
|
||||
await cdp.call("Runtime.enable");
|
||||
timer = timeout(10000);
|
||||
await Promise.race([wait, timer.promise]);
|
||||
} finally {
|
||||
if (timer) {
|
||||
timer.cancel();
|
||||
}
|
||||
wsConn.close();
|
||||
}
|
||||
}
|
||||
|
||||
run().catch(e => {
|
||||
console.error("Error", e);
|
||||
});
|
19
tests/src/test/js/test/only/test.js
Normal file
19
tests/src/test/js/test/only/test.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright 2019 Alexey Andreev.
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
function main(args, callback) {
|
||||
callback();
|
||||
}
|
Loading…
Reference in New Issue
Block a user