|
1 | 1 | /* global vm, Promise */ |
2 | | -const {Chromeless} = require('chromeless'); |
| 2 | +const {chromium} = require('playwright-chromium'); |
3 | 3 | const test = require('tap').test; |
4 | 4 | const path = require('path'); |
5 | 5 | const fs = require('fs'); |
6 | | -const chromeless = new Chromeless(); |
7 | 6 |
|
8 | 7 | const indexHTML = path.resolve(__dirname, 'index.html'); |
9 | 8 | const testDir = (...args) => path.resolve(__dirname, 'scratch-tests', ...args); |
10 | 9 |
|
11 | | -const testFile = file => test(file, async t => { |
| 10 | +const testFile = (file, page) => test(file, async t => { |
12 | 11 | // start each test by going to the index.html, and loading the scratch file |
13 | | - const says = await chromeless.goto(`file://${indexHTML}`) |
14 | | - .setFileInput('#file', testDir(file)) |
15 | | - // the index.html handler for file input will add a #loaded element when it |
16 | | - // finishes. |
17 | | - .wait('#loaded') |
18 | | - .evaluate(() => { |
19 | | - // This function is run INSIDE the integration chrome browser via some |
20 | | - // injection and .toString() magic. We can return some "simple data" |
21 | | - // back across as a promise, so we will just log all the says that happen |
22 | | - // for parsing after. |
23 | | - |
24 | | - // this becomes the `says` in the outer scope |
25 | | - const messages = []; |
26 | | - const TIMEOUT = 5000; |
27 | | - |
28 | | - vm.runtime.on('SAY', (_, __, message) => { |
29 | | - messages.push(message); |
30 | | - }); |
| 12 | + await page.goto(`file://${indexHTML}`); |
| 13 | + const fileInput = await page.$('#file'); |
| 14 | + await fileInput.setInputFiles(testDir(file)); |
| 15 | + await page.evaluate(() => |
| 16 | + // `loadFile` is defined on the page itself. |
| 17 | + // eslint-disable-next-line no-undef |
| 18 | + loadFile() |
| 19 | + ); |
| 20 | + const says = await page.evaluate(() => { |
| 21 | + // This function is run INSIDE the integration chrome browser via some |
| 22 | + // injection and .toString() magic. We can return some "simple data" |
| 23 | + // back across as a promise, so we will just log all the says that happen |
| 24 | + // for parsing after. |
| 25 | + |
| 26 | + // this becomes the `says` in the outer scope |
| 27 | + const messages = []; |
| 28 | + const TIMEOUT = 5000; |
| 29 | + |
| 30 | + vm.runtime.on('SAY', (_, __, message) => { |
| 31 | + messages.push(message); |
| 32 | + }); |
31 | 33 |
|
32 | | - vm.greenFlag(); |
33 | | - const startTime = Date.now(); |
34 | | - |
35 | | - return Promise.resolve() |
36 | | - .then(async () => { |
37 | | - // waiting for all threads to complete, then we return |
38 | | - while (vm.runtime.threads.some(thread => vm.runtime.isActiveThread(thread))) { |
39 | | - if ((Date.now() - startTime) >= TIMEOUT) { |
40 | | - // if we push the message after end, the failure from tap is not very useful: |
41 | | - // "not ok test after end() was called" |
42 | | - messages.unshift(`fail Threads still running after ${TIMEOUT}ms`); |
43 | | - break; |
44 | | - } |
45 | | - |
46 | | - await new Promise(resolve => setTimeout(resolve, 50)); |
| 34 | + vm.greenFlag(); |
| 35 | + const startTime = Date.now(); |
| 36 | + |
| 37 | + return Promise.resolve() |
| 38 | + .then(async () => { |
| 39 | + // waiting for all threads to complete, then we return |
| 40 | + while (vm.runtime.threads.some(thread => vm.runtime.isActiveThread(thread))) { |
| 41 | + if ((Date.now() - startTime) >= TIMEOUT) { |
| 42 | + // if we push the message after end, the failure from tap is not very useful: |
| 43 | + // "not ok test after end() was called" |
| 44 | + messages.unshift(`fail Threads still running after ${TIMEOUT}ms`); |
| 45 | + break; |
47 | 46 | } |
48 | 47 |
|
49 | | - return messages; |
50 | | - }); |
51 | | - }); |
| 48 | + await new Promise(resolve => setTimeout(resolve, 50)); |
| 49 | + } |
| 50 | + |
| 51 | + return messages; |
| 52 | + }); |
| 53 | + }); |
52 | 54 |
|
53 | 55 | // Map string messages to tap reporting methods. This will be used |
54 | 56 | // with events from scratch's runtime emitted on block instructions. |
@@ -103,13 +105,21 @@ const testFile = file => test(file, async t => { |
103 | 105 |
|
104 | 106 | // immediately invoked async function to let us wait for each test to finish before starting the next. |
105 | 107 | (async () => { |
| 108 | + const browser = await chromium.launch(); |
| 109 | + const page = await browser.newPage(); |
| 110 | + |
106 | 111 | const files = fs.readdirSync(testDir()) |
107 | 112 | .filter(uri => uri.endsWith('.sb2') || uri.endsWith('.sb3')); |
108 | 113 |
|
109 | 114 | for (const file of files) { |
110 | | - await testFile(file); |
| 115 | + await testFile(file, page); |
111 | 116 | } |
112 | 117 |
|
113 | 118 | // close the browser window we used |
114 | | - await chromeless.end(); |
115 | | -})(); |
| 119 | + await browser.close(); |
| 120 | +})().catch(err => { |
| 121 | + // Handle promise rejections by exiting with a nonzero code to ensure that tests don't erroneously pass |
| 122 | + // eslint-disable-next-line no-console |
| 123 | + console.error(err.message); |
| 124 | + process.exit(1); |
| 125 | +}); |
0 commit comments