]> git.localhorst.tv Git - aosr-cli.git/blob - app.js
add command line wrapper
[aosr-cli.git] / app.js
1 const fs = require('fs');
2 const jsdom = require('jsdom');
3 const path = require('path');
4
5 const inPath = process.argv[2];
6 const outPath = process.argv[3];
7 const settings = process.argv[4] || 'seed=0';
8
9 const sleep = ms => new Promise(resolve => { setTimeout(resolve, ms); });
10
11 const getElement = (document, selector, index) => {
12         const elements = document.querySelectorAll(selector);
13         if (elements.length - 1 >= index) {
14                 return elements[index];
15         }
16         return null;
17 };
18
19 const waitForElement = async (document, selector, index) => {
20         let element = getElement(document, selector, index);
21         if (element) {
22                 return element;
23         }
24         await sleep(100);
25         element = getElement(document, selector, index);
26         if (element) {
27                 return element;
28         }
29         await sleep(100);
30         element = getElement(document, selector, index);
31         if (element) {
32                 return element;
33         }
34         await sleep(200);
35         element = getElement(document, selector, index);
36         if (element) {
37                 return element;
38         }
39         await sleep(200);
40         element = getElement(document, selector, index);
41         if (element) {
42                 return element;
43         }
44         await sleep(300);
45         element = getElement(document, selector, index);
46         if (element) {
47                 return element;
48         }
49         await sleep(400);
50         element = getElement(document, selector, index);
51         if (element) {
52                 return element;
53         }
54         await sleep(500);
55         element = getElement(document, selector, index);
56         if (element) {
57                 return element;
58         }
59         throw new Error('timeout waiting for element');
60 };
61
62 (async () => {
63
64 const { JSDOM } = jsdom;
65 const dom = await JSDOM.fromURL('https://aos.localhorst.tv/surge/?' + settings, {
66         resources: 'usable',
67         runScripts: 'dangerously',
68         storageQuota: 10000000,
69 });
70
71 const { window } = dom;
72 const { document, File, FileList, FileReader } = window;
73
74 const blobToBuffer = blob => new Promise((resolve, reject) => {
75         const reader = new FileReader();
76         reader.addEventListener('loadend', e => {
77                 if (e.error) {
78                         reject(e.error);
79                 } else {
80                         resolve(Buffer.from(reader.result));
81                 }
82         }, false);
83         reader.readAsArrayBuffer(blob);
84 });
85
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);
91                 el.dispatchEvent(e);
92         } else if (document.createEventObject) {
93                 el.fireEvent('on' + eventName);
94         } else if (typeof el['on' + eventName] === 'function') {
95                 el['on' + eventName]();
96         }
97 }
98
99 const createFile = filePath => {
100         return new File(
101                 [new fs.readFileSync(filePath)],
102                 path.basename(filePath),
103         );
104 }
105
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', {
111                 value: fileList,
112                 writable: false
113         });
114         fireEvent(input, 'change');
115 }
116
117 Object.defineProperty(window.URL, 'createObjectURL', {
118         value: async blob => {
119                 const buffer = await blobToBuffer(blob);
120                 fs.writeFile(outPath, buffer, err => {
121                         if (err) {
122                                 throw new Error('failed to write file');
123                         }
124                 });
125                 return 'a';
126         },
127 });
128
129 const fileInput = await waitForElement(document, 'input[type=file]', 0);
130 addFiles(fileInput, [inPath]);
131
132 try {
133         await waitForElement(document, 'select', 0);
134         const button = await waitForElement(document, 'button', 1);
135         fireEvent(button, 'click');
136 } catch (e) {
137         console.log(dom.serialize());
138         throw e;
139 }
140
141 })().catch(e => {
142         console.log(e);
143         return 1;
144 });