]> git.localhorst.tv Git - aosr-cli.git/blobdiff - app.js
first version
[aosr-cli.git] / app.js
diff --git a/app.js b/app.js
new file mode 100644 (file)
index 0000000..b6ce6bd
--- /dev/null
+++ b/app.js
@@ -0,0 +1,144 @@
+const fs = require('fs');
+const jsdom = require('jsdom');
+const path = require('path');
+
+const inPath = process.argv[2];
+const outPath = process.argv[3];
+const settings = process.argv[4] || 'seed=0';
+
+const sleep = ms => new Promise(resolve => { setTimeout(resolve, ms); });
+
+const getElement = (document, selector, index) => {
+       const elements = document.querySelectorAll(selector);
+       if (elements.length - 1 >= index) {
+               return elements[index];
+       }
+       return null;
+};
+
+const waitForElement = async (document, selector, index) => {
+       let element = getElement(document, selector, index);
+       if (element) {
+               return element;
+       }
+       await sleep(100);
+       element = getElement(document, selector, index);
+       if (element) {
+               return element;
+       }
+       await sleep(100);
+       element = getElement(document, selector, index);
+       if (element) {
+               return element;
+       }
+       await sleep(200);
+       element = getElement(document, selector, index);
+       if (element) {
+               return element;
+       }
+       await sleep(200);
+       element = getElement(document, selector, index);
+       if (element) {
+               return element;
+       }
+       await sleep(300);
+       element = getElement(document, selector, index);
+       if (element) {
+               return element;
+       }
+       await sleep(400);
+       element = getElement(document, selector, index);
+       if (element) {
+               return element;
+       }
+       await sleep(500);
+       element = getElement(document, selector, index);
+       if (element) {
+               return element;
+       }
+       throw new Error('timeout waiting for element');
+};
+
+(async () => {
+
+const { JSDOM } = jsdom;
+const dom = await JSDOM.fromURL('https://aos.localhorst.tv/surge/?' + settings, {
+       resources: 'usable',
+       runScripts: 'dangerously',
+       storageQuota: 10000000,
+});
+
+const { window } = dom;
+const { document, File, FileList, FileReader } = window;
+
+const blobToBuffer = blob => new Promise((resolve, reject) => {
+       const reader = new FileReader();
+       reader.addEventListener('loadend', e => {
+               if (e.error) {
+                       reject(e.error);
+               } else {
+                       resolve(Buffer.from(reader.result));
+               }
+       }, false);
+       reader.readAsArrayBuffer(blob);
+});
+
+const fireEvent = (el, eventName) => {
+       eventName = eventName.replace(/on/, '');
+       if (document.createEvent) {
+               var e = document.createEvent('Event');
+               e.initEvent(eventName, true, true);
+               el.dispatchEvent(e);
+       } else if (document.createEventObject) {
+               el.fireEvent('on' + eventName);
+       } else if (typeof el['on' + eventName] === 'function') {
+               el['on' + eventName]();
+       }
+}
+
+const createFile = filePath => {
+       return new File(
+               [new fs.readFileSync(filePath)],
+               path.basename(filePath),
+       );
+}
+
+const addFiles = (input, filePaths) => {
+       if (!Array.isArray(filePaths)) throw new Error('filePaths needs to be a file path string or an Array of file path strings');
+       const fileList = filePaths.map(fp => createFile(fp));
+       fileList.__proto__ = Object.create(FileList.prototype);
+       Object.defineProperty(input, 'files', {
+               value: fileList,
+               writable: false
+       });
+       fireEvent(input, 'change');
+}
+
+Object.defineProperty(window.URL, 'createObjectURL', {
+       value: async blob => {
+               const buffer = await blobToBuffer(blob);
+               fs.writeFile(outPath, buffer, err => {
+                       if (err) {
+                               throw new Error('failed to write file');
+                       }
+               });
+               return 'a';
+       },
+});
+
+const fileInput = await waitForElement(document, 'input[type=file]', 0);
+addFiles(fileInput, [inPath]);
+
+try {
+       await waitForElement(document, 'select', 0);
+       const button = await waitForElement(document, 'button', 1);
+       fireEvent(button, 'click');
+} catch (e) {
+       console.log(dom.serialize());
+       throw e;
+}
+
+})().catch(e => {
+       console.log(e);
+       return 1;
+});