((resolve, reject) => {
console.info("Loading map related script at ", scriptUrl);
@@ -283,7 +283,11 @@ class IframeListener {
const iframe = document.createElement("iframe");
iframe.id = IframeListener.getIFrameId(scriptUrl);
iframe.style.display = "none";
- iframe.src = "/iframe.html?script=" + encodeURIComponent(scriptUrl);
+ iframe.src =
+ "/iframe.html?script=" +
+ encodeURIComponent(scriptUrl) +
+ "&moduleMode=" +
+ (enableModuleMode ? "true" : "false");
// We are putting a sandbox on this script because it will run in the same domain as the main website.
iframe.sandbox.add("allow-scripts");
@@ -318,7 +322,9 @@ class IframeListener {
"//" +
window.location.host +
'/iframe_api.js" >\n' +
- '\n' +
"\n" +
diff --git a/front/src/Phaser/Game/GameMapProperties.ts b/front/src/Phaser/Game/GameMapProperties.ts
index 65ce6ab8..b77bd02b 100644
--- a/front/src/Phaser/Game/GameMapProperties.ts
+++ b/front/src/Phaser/Game/GameMapProperties.ts
@@ -28,6 +28,7 @@ export enum GameMapProperties {
PLAY_AUDIO_LOOP = "playAudioLoop",
READABLE_BY = "readableBy",
SCRIPT = "script",
+ SCRIPT_DISABLE_MODULE_SUPPORT = "scriptDisableModuleSupport",
SILENT = "silent",
START = "start",
START_LAYER = "startLayer",
diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts
index 740de4c1..6b449948 100644
--- a/front/src/Phaser/Game/GameScene.ts
+++ b/front/src/Phaser/Game/GameScene.ts
@@ -597,9 +597,12 @@ export class GameScene extends DirtyScene {
this.createPromiseResolve();
// Now, let's load the script, if any
const scripts = this.getScriptUrls(this.mapFile);
+ const disableModuleMode = this.getProperty(this.mapFile, GameMapProperties.SCRIPT_DISABLE_MODULE_SUPPORT) as
+ | boolean
+ | undefined;
const scriptPromises = [];
for (const script of scripts) {
- scriptPromises.push(iframeListener.registerScript(script));
+ scriptPromises.push(iframeListener.registerScript(script, !disableModuleMode));
}
this.userInputManager.spaceEvent(() => {
diff --git a/maps/tests/Modules/module.js b/maps/tests/Modules/module.js
new file mode 100644
index 00000000..d407b060
--- /dev/null
+++ b/maps/tests/Modules/module.js
@@ -0,0 +1 @@
+export const foo = "bar";
diff --git a/maps/tests/Modules/script.js b/maps/tests/Modules/script.js
new file mode 100644
index 00000000..578a7148
--- /dev/null
+++ b/maps/tests/Modules/script.js
@@ -0,0 +1,3 @@
+import { foo } from './module.js';
+
+console.log('Successfully loaded module: foo = ', foo);
diff --git a/maps/tests/Modules/with_modules.json b/maps/tests/Modules/with_modules.json
new file mode 100644
index 00000000..2dd40427
--- /dev/null
+++ b/maps/tests/Modules/with_modules.json
@@ -0,0 +1,88 @@
+{ "compressionlevel":-1,
+ "height":10,
+ "infinite":false,
+ "layers":[
+ {
+ "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+ "height":10,
+ "id":1,
+ "name":"floor",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":true,
+ "width":10,
+ "x":0,
+ "y":0
+ },
+ {
+ "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "height":10,
+ "id":2,
+ "name":"start",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":true,
+ "width":10,
+ "x":0,
+ "y":0
+ },
+ {
+ "draworder":"topdown",
+ "id":3,
+ "name":"floorLayer",
+ "objects":[
+ {
+ "height":304.037037037037,
+ "id":3,
+ "name":"",
+ "rotation":0,
+ "text":
+ {
+ "fontfamily":"Sans Serif",
+ "pixelsize":11,
+ "text":"Test:\nOpen the console.\nThe script loaded loads modules. This should work.\n\nYou should see in the console:\n\nSuccessfully loaded module: foo = \"bar\"",
+ "wrap":true
+ },
+ "type":"",
+ "visible":true,
+ "width":252.4375,
+ "x":2.78125,
+ "y":2.5
+ }],
+ "opacity":1,
+ "type":"objectgroup",
+ "visible":true,
+ "x":0,
+ "y":0
+ }],
+ "nextlayerid":9,
+ "nextobjectid":11,
+ "orientation":"orthogonal",
+ "properties":[
+ {
+ "name":"script",
+ "type":"string",
+ "value":"script.js"
+ }],
+ "renderorder":"right-down",
+ "tiledversion":"2021.03.23",
+ "tileheight":32,
+ "tilesets":[
+ {
+ "columns":11,
+ "firstgid":1,
+ "image":"..\/tileset1.png",
+ "imageheight":352,
+ "imagewidth":352,
+ "margin":0,
+ "name":"tileset1",
+ "spacing":0,
+ "tilecount":121,
+ "tileheight":32,
+ "tilewidth":32
+ }],
+ "tilewidth":32,
+ "type":"map",
+ "version":1.5,
+ "width":10
+}
\ No newline at end of file
diff --git a/maps/tests/Modules/without_modules.json b/maps/tests/Modules/without_modules.json
new file mode 100644
index 00000000..4b64af57
--- /dev/null
+++ b/maps/tests/Modules/without_modules.json
@@ -0,0 +1,93 @@
+{ "compressionlevel":-1,
+ "height":10,
+ "infinite":false,
+ "layers":[
+ {
+ "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
+ "height":10,
+ "id":1,
+ "name":"floor",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":true,
+ "width":10,
+ "x":0,
+ "y":0
+ },
+ {
+ "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "height":10,
+ "id":2,
+ "name":"start",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":true,
+ "width":10,
+ "x":0,
+ "y":0
+ },
+ {
+ "draworder":"topdown",
+ "id":3,
+ "name":"floorLayer",
+ "objects":[
+ {
+ "height":304.037037037037,
+ "id":3,
+ "name":"",
+ "rotation":0,
+ "text":
+ {
+ "fontfamily":"Sans Serif",
+ "pixelsize":11,
+ "text":"Test:\nOpen the console.\nThe script loaded loads modules. This should fail because we disallow modules.\n\nYou should see in the console this error message:\n\nUncaught SyntaxError: Cannot use import statement outside a module",
+ "wrap":true
+ },
+ "type":"",
+ "visible":true,
+ "width":252.4375,
+ "x":2.78125,
+ "y":2.5
+ }],
+ "opacity":1,
+ "type":"objectgroup",
+ "visible":true,
+ "x":0,
+ "y":0
+ }],
+ "nextlayerid":9,
+ "nextobjectid":11,
+ "orientation":"orthogonal",
+ "properties":[
+ {
+ "name":"script",
+ "type":"string",
+ "value":"script.js"
+ },
+ {
+ "name":"scriptDisableModuleSupport",
+ "type":"bool",
+ "value":true
+ }],
+ "renderorder":"right-down",
+ "tiledversion":"2021.03.23",
+ "tileheight":32,
+ "tilesets":[
+ {
+ "columns":11,
+ "firstgid":1,
+ "image":"..\/tileset1.png",
+ "imageheight":352,
+ "imagewidth":352,
+ "margin":0,
+ "name":"tileset1",
+ "spacing":0,
+ "tilecount":121,
+ "tileheight":32,
+ "tilewidth":32
+ }],
+ "tilewidth":32,
+ "type":"map",
+ "version":1.5,
+ "width":10
+}
\ No newline at end of file
diff --git a/maps/tests/index.html b/maps/tests/index.html
index 573c02f7..a3b937e3 100644
--- a/maps/tests/index.html
+++ b/maps/tests/index.html
@@ -275,6 +275,22 @@
Testing scripting API for outline on players
+
+
+ Success Failure Pending
+ |
+
+ Testing scripts with modules
+ |
+
+
+
+ Success Failure Pending
+ |
+
+ Testing scripts with modules mode disabled
+ |
+
CoWebsite
diff --git a/tests/tests/modules.ts b/tests/tests/modules.ts
new file mode 100644
index 00000000..86f7a374
--- /dev/null
+++ b/tests/tests/modules.ts
@@ -0,0 +1,44 @@
+import {assertLogMessage} from "./utils/log";
+
+const fs = require('fs');
+const Docker = require('dockerode');
+import { Selector } from 'testcafe';
+import {login} from "./utils/roles";
+import {
+ findContainer,
+ rebootBack,
+ rebootPusher,
+ resetRedis,
+ rebootTraefik,
+ startContainer,
+ stopContainer, stopRedis, startRedis
+} from "./utils/containers";
+import {getBackDump, getPusherDump} from "./utils/debug";
+
+fixture `Modules`
+ .page `http://play.workadventure.localhost/_/global/maps.workadventure.localhost/tests/Modules/with_modules.json`;
+
+test("Test that module loading works out of the box", async (t: TestController) => {
+
+ await login(t, 'http://play.workadventure.localhost/_/global/maps.workadventure.localhost/tests/Modules/with_modules.json');
+
+
+ await assertLogMessage(t, 'Successfully loaded module: foo = bar');
+
+ t.ctx.passed = true;
+}).after(async t => {
+ if (!t.ctx.passed) {
+ console.log("Test 'Test that module loading works out of the box' failed. Browser logs:")
+ try {
+ console.log(await t.getBrowserConsoleMessages());
+ } catch (e) {
+ console.error('Error while fetching browser logs (maybe linked to a closed iframe?)', e);
+ try {
+ console.log('Logs from main window:');
+ console.log(await t.switchToMainWindow().getBrowserConsoleMessages());
+ } catch (e) {
+ console.error('Unable to retrieve logs', e);
+ }
+ }
+ }
+});