arce
v0.5.0
Published
(A)rbitrary (R)emote (C)ode (E)xecutor: Experimental tool for browser agnostic e2e testing.
Downloads
5
Maintainers
Readme
ARCE: Arbitrary Remote Code Executor
An experimental attempt to send arbitrary JavaScript commands to a webapp via a websocket server proxy.
Should not be used anywhere near production or for any malicious purposes!
How is this useful?
This package tries to be a browser-agnostic alternative to tools like puppeteer, playwright, selenium etc., which either use the chrome devtools protocol, webdrivers and/or need the browser to be opened with specific args to work.
Any of the above-mentioned tools should likely be preferred over 'arce', but in scenarios where you have limited control over how a browser is opened (for example: a webapp shown in a webview embedded in some desktop app) and need to e2e test a variety of otherwise unsupported browsers, this kind of websocket proxy might work.
Install
npm install arce
or
yarn add arce
Usage
Start websocket server proxy:
npx arce --ssl_cert=example.crt --ssl_key=example.key
Include this script in your index.html to automatically open websocket connection:
<script src="https://localhost:12000/client"></script>
Open https://localhost:12000/public/example-client.html (has the above script already included)
Send a POST request to https://localhost:12000/command?foo=hello&bar=world with the following body:
async ({waitUntil, capture, done, global, scriptContext}) => { capture(scriptContext.foo); setTimeout(() => document.querySelector('button').click(), 1500); // waits for list to be visible const list = await waitUntil(() => document.querySelector('ul:not(.hidden)')); let i = 0; // Scroll to random list item every 0.3s const handler = setInterval(() => { const randIndex = Math.floor(Math.random() * list.children.length); const li = list.children[randIndex]; capture(li.innerText); // value to be included with the http response li.scrollIntoView({ behavior: "smooth", block: "center" }); if (++i > 10) { clearInterval(handler); document.body.style.backgroundColor = 'salmon'; capture(scriptContext.bar); done(); } }, 300); };
Which will result in the following response:
{ "status": 200, "script": "<The script fn (as a string) sent within body>", "awaitId": "a35339e3-14d6-48ec-bb2b-0cdc7c81f363", "scriptContext": {"foo": "hello", "bar": "world"}, "captures": [ "hello", "Item 07", "Item 01", "Item 05", "Item 08", "...", "...", "world" ] }
The code sent within the POST request is run directly on the connected client, so you have pretty much full access to the runtime to automate things and make assertions.
License
MIT