diff --git a/.travis.yml b/.travis.yml
index 969909f79..f3da52b33 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,14 +1,10 @@
language: node_js
dist: trusty
-addons:
- chrome: stable
node_js:
- 8
- node
env:
- NODE_ENV=production
-before_install:
- - google-chrome-stable --headless --no-sandbox --remote-debugging-port=9222 &
install:
- npm --production=false install
- npm --production=false update
diff --git a/package.json b/package.json
index 91c1c6de3..213244c3b 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,6 @@
"babel-loader": "^7.1.4",
"babel-polyfill": "^6.22.0",
"babel-preset-env": "^1.6.1",
- "chromeless": "^1.5.1",
"copy-webpack-plugin": "^4.5.1",
"docdash": "^0.4.0",
"eslint": "^4.6.1",
@@ -37,6 +36,7 @@
"gh-pages": "^1.0.0",
"jsdoc": "^3.5.5",
"json": "^9.0.4",
+ "puppeteer-core": "^2.0.0",
"scratch-vm": "0.2.0-prerelease.20191227164934",
"tap": "^11.0.0",
"travis-after-all": "^1.4.4",
diff --git a/test/helper/download-chromium.js b/test/helper/download-chromium.js
new file mode 100644
index 000000000..dc475a155
--- /dev/null
+++ b/test/helper/download-chromium.js
@@ -0,0 +1,24 @@
+const packageJson = require('puppeteer-core/package.json');
+const puppeteer = require('puppeteer-core');
+
+const fetcher = puppeteer.createBrowserFetcher();
+const revision = packageJson.puppeteer.chromium_revision;
+
+/* eslint-disable no-console */
+module.exports = async () => {
+ const downloadedRevisions = await fetcher.localRevisions();
+ if (downloadedRevisions.indexOf(revision) !== -1) {
+ console.log('Chromium already downloaded');
+ return Promise.resolve();
+ }
+
+ console.log('Downloading Chromium...');
+ return fetcher.download(revision)
+ .then(() => {
+ console.log('Downloaded Chromium successfully');
+ })
+ .catch(error => {
+ console.error(error);
+ process.exit(1);
+ });
+};
diff --git a/test/helper/page-util.js b/test/helper/page-util.js
new file mode 100644
index 000000000..25f5b007e
--- /dev/null
+++ b/test/helper/page-util.js
@@ -0,0 +1,54 @@
+/* global window, VirtualMachine, ScratchStorage, ScratchSVGRenderer */
+/* eslint-env browser */
+
+// Wait for all SVG skins to be loaded.
+// TODO: this is extremely janky and should be removed once vm.loadProject waits for SVG skins to load
+// https://github.com/LLK/scratch-render/issues/563
+window.waitForSVGSkinLoad = renderer => new Promise(resolve => {
+ // eslint-disable-next-line prefer-const
+ let interval;
+
+ const waitInner = () => {
+ let numSVGSkins = 0;
+ let numLoadedSVGSkins = 0;
+ for (const skin of renderer._allSkins) {
+ if (skin.constructor.name !== 'SVGSkin') continue;
+ numSVGSkins++;
+ if (skin._svgRenderer.loaded) numLoadedSVGSkins++;
+ }
+
+ if (numSVGSkins === numLoadedSVGSkins) {
+ clearInterval(interval);
+ resolve();
+ }
+ };
+
+ interval = setInterval(waitInner, 1);
+});
+
+window.loadFileInputIntoVM = (fileInput, vm, render) => {
+ const reader = new FileReader();
+ return new Promise(resolve => {
+ reader.onload = () => {
+ vm.start();
+ vm.loadProject(reader.result)
+ .then(() => window.waitForSVGSkinLoad(render))
+ .then(() => {
+ resolve();
+ });
+ };
+ reader.readAsArrayBuffer(fileInput.files[0]);
+ });
+};
+
+window.initVM = render => {
+ const vm = new VirtualMachine();
+ const storage = new ScratchStorage();
+
+ vm.attachStorage(storage);
+ vm.attachRenderer(render);
+ vm.attachV2SVGAdapter(new ScratchSVGRenderer.SVGRenderer());
+ vm.attachV2BitmapAdapter(new ScratchSVGRenderer.BitmapAdapter());
+
+ return vm;
+};
diff --git a/test/integration/cpu-render.html b/test/integration/cpu-render.html
index d6d363084..26a79c3f4 100644
--- a/test/integration/cpu-render.html
+++ b/test/integration/cpu-render.html
@@ -2,6 +2,7 @@
+
@@ -17,38 +18,18 @@
window.devicePixelRatio = 1;
const gpuCanvas = document.getElementById('test');
var render = new ScratchRender(gpuCanvas);
- var vm = new VirtualMachine();
- var storage = new ScratchStorage();
+ var vm = initVM(render);
- vm.attachStorage(storage);
- vm.attachRenderer(render);
- vm.attachV2SVGAdapter(new ScratchSVGRenderer.SVGRenderer());
- vm.attachV2BitmapAdapter(new ScratchSVGRenderer.BitmapAdapter());
-
- document.getElementById('file').addEventListener('click', e => {
- document.body.removeChild(document.getElementById('loaded'));
- });
-
- document.getElementById('file').addEventListener('change', e => {
- const reader = new FileReader();
- const thisFileInput = e.target;
- reader.onload = () => {
- vm.start();
- vm.loadProject(reader.result)
- .then(() => {
- // we add a `#loaded` div to our document, the integration suite
- // waits for that element to show up to assume the vm is ready
- // to play!
- const div = document.createElement('div');
- div.id='loaded';
- document.body.appendChild(div);
- vm.greenFlag();
- setTimeout(() => {
- renderCpu();
- }, 1000);
- });
- };
- reader.readAsArrayBuffer(thisFileInput.files[0]);
+ const fileInput = document.getElementById('file');
+ const loadFile = loadFileInputIntoVM.bind(null, fileInput, vm, render);
+ fileInput.addEventListener('change', e => {
+ loadFile()
+ .then(() => {
+ vm.greenFlag();
+ setTimeout(() => {
+ renderCpu();
+ }, 1000);
+ });
});
const cpuCanvas = document.getElementById('cpu');
diff --git a/test/integration/index.html b/test/integration/index.html
index e3d8dd838..114fa5b9d 100644
--- a/test/integration/index.html
+++ b/test/integration/index.html
@@ -2,6 +2,7 @@
+
@@ -15,39 +16,13 @@
var canvas = document.getElementById('test');
var render = new ScratchRender(canvas);
- var vm = new VirtualMachine();
- var storage = new ScratchStorage();
+ var vm = initVM(render);
var mockMouse = data => vm.runtime.postIOData('mouse', {
canvasWidth: canvas.width,
canvasHeight: canvas.height,
...data,
});
- vm.attachStorage(storage);
- vm.attachRenderer(render);
- vm.attachV2SVGAdapter(new ScratchSVGRenderer.SVGRenderer());
- vm.attachV2BitmapAdapter(new ScratchSVGRenderer.BitmapAdapter());
-
- document.getElementById('file').addEventListener('click', e => {
- document.body.removeChild(document.getElementById('loaded'));
- });
-
- document.getElementById('file').addEventListener('change', e => {
- const reader = new FileReader();
- const thisFileInput = e.target;
- reader.onload = () => {
- vm.start();
- vm.loadProject(reader.result)
- .then(() => {
- // we add a `#loaded` div to our document, the integration suite
- // waits for that element to show up to assume the vm is ready
- // to play!
- const div = document.createElement('div');
- div.id='loaded';
- document.body.appendChild(div);
- });
- };
- reader.readAsArrayBuffer(thisFileInput.files[0]);
- });
+ const loadFile = loadFileInputIntoVM.bind(null, document.getElementById('file'), vm, render);