1 const fs = require('fs');
2 const jsdom = require('jsdom');
3 const path = require('path');
5 const inPath = process.argv[2];
6 const outPath = process.argv[3];
7 const settings = process.argv[4] || 'seed=0';
9 const sleep = ms => new Promise(resolve => { setTimeout(resolve, ms); });
11 const getElement = (document, selector, index) => {
12 const elements = document.querySelectorAll(selector);
13 if (elements.length - 1 >= index) {
14 return elements[index];
19 const waitForElement = async (document, selector, index) => {
20 let element = getElement(document, selector, index);
25 element = getElement(document, selector, index);
30 element = getElement(document, selector, index);
35 element = getElement(document, selector, index);
40 element = getElement(document, selector, index);
45 element = getElement(document, selector, index);
50 element = getElement(document, selector, index);
55 element = getElement(document, selector, index);
59 throw new Error('timeout waiting for element');
64 const { JSDOM } = jsdom;
65 const dom = await JSDOM.fromURL('https://aos.localhorst.tv/surge/?' + settings, {
67 runScripts: 'dangerously',
68 storageQuota: 10000000,
71 const { window } = dom;
72 const { document, File, FileList, FileReader } = window;
74 const blobToBuffer = blob => new Promise((resolve, reject) => {
75 const reader = new FileReader();
76 reader.addEventListener('loadend', e => {
80 resolve(Buffer.from(reader.result));
83 reader.readAsArrayBuffer(blob);
86 const fireEvent = (el, eventName) => {
87 eventName = eventName.replace(/on/, '');
88 if (document.createEvent) {
89 var e = document.createEvent('Event');
90 e.initEvent(eventName, true, true);
92 } else if (document.createEventObject) {
93 el.fireEvent('on' + eventName);
94 } else if (typeof el['on' + eventName] === 'function') {
95 el['on' + eventName]();
99 const createFile = filePath => {
101 [new fs.readFileSync(filePath)],
102 path.basename(filePath),
106 const addFiles = (input, filePaths) => {
107 if (!Array.isArray(filePaths)) throw new Error('filePaths needs to be a file path string or an Array of file path strings');
108 const fileList = filePaths.map(fp => createFile(fp));
109 fileList.__proto__ = Object.create(FileList.prototype);
110 Object.defineProperty(input, 'files', {
114 fireEvent(input, 'change');
117 Object.defineProperty(window.URL, 'createObjectURL', {
118 value: async blob => {
119 const buffer = await blobToBuffer(blob);
120 fs.writeFile(outPath, buffer, err => {
122 throw new Error('failed to write file');
129 const fileInput = await waitForElement(document, 'input[type=file]', 0);
130 addFiles(fileInput, [inPath]);
133 await waitForElement(document, 'select', 0);
134 const button = await waitForElement(document, 'button', 1);
135 fireEvent(button, 'click');
137 console.log(dom.serialize());