From 1918227c810d44b318aa24c480bfeb3b9c55979f Mon Sep 17 00:00:00 2001 From: juliandescottes Date: Sun, 29 Jan 2017 13:56:06 +0100 Subject: [PATCH] add integration tests for PNG export & scaled export --- .../exportimage/PngExportController.js | 4 + src/js/utils/FrameUtils.js | 13 ++ test/casperjs/integration/IntegrationSuite.js | 3 + test/casperjs/integration/include.js | 47 ++++++- .../settings/test-export-gif-scale.js | 116 +++++++++++++++++ .../settings/test-export-gif-simple.js | 105 +++++++++++++++ .../integration/settings/test-export-gif.js | 98 ++++++-------- .../settings/test-export-png-scale.js | 120 ++++++++++++++++++ .../integration/settings/test-export-png.js | 109 ++++++++++++++++ 9 files changed, 554 insertions(+), 61 deletions(-) create mode 100644 test/casperjs/integration/settings/test-export-gif-scale.js create mode 100644 test/casperjs/integration/settings/test-export-gif-simple.js create mode 100644 test/casperjs/integration/settings/test-export-png-scale.js create mode 100644 test/casperjs/integration/settings/test-export-png.js diff --git a/src/js/controller/settings/exportimage/PngExportController.js b/src/js/controller/settings/exportimage/PngExportController.js index 94d809a9..314cc3ee 100644 --- a/src/js/controller/settings/exportimage/PngExportController.js +++ b/src/js/controller/settings/exportimage/PngExportController.js @@ -145,7 +145,11 @@ ns.PngExportController.prototype.onDownloadClick_ = function (evt) { // Create PNG export. var canvas = this.createPngSpritesheet_(); + this.downloadCanvas_(canvas); + }; + // Used and overridden in casper integration tests. + ns.PngExportController.prototype.downloadCanvas_ = function (canvas) { // Generate file name var name = this.piskelController.getPiskel().getDescriptor().name; var fileName = name + '.png'; diff --git a/src/js/utils/FrameUtils.js b/src/js/utils/FrameUtils.js index e604f85d..b91aed5a 100644 --- a/src/js/utils/FrameUtils.js +++ b/src/js/utils/FrameUtils.js @@ -269,6 +269,19 @@ } return chunkFrames; + }, + + toFrameGrid : function (normalGrid) { + var frameGrid = []; + var w = normalGrid[0].length; + var h = normalGrid.length; + for (var x = 0 ; x < w ; x++) { + frameGrid[x] = []; + for (var y = 0 ; y < h ; y++) { + frameGrid[x][y] = normalGrid[y][x]; + } + } + return frameGrid; } }; })(); diff --git a/test/casperjs/integration/IntegrationSuite.js b/test/casperjs/integration/IntegrationSuite.js index 095c3139..f513793a 100644 --- a/test/casperjs/integration/IntegrationSuite.js +++ b/test/casperjs/integration/IntegrationSuite.js @@ -1,5 +1,8 @@ (typeof exports != "undefined" ? exports : pskl_exports).tests = [ 'settings/test-export-gif.js', + 'settings/test-export-gif-simple.js', + 'settings/test-export-png.js', + 'settings/test-export-png-scale.js', 'settings/test-resize-complete.js', 'settings/test-resize-content-complete.js', 'settings/test-resize-default-size.js', diff --git a/test/casperjs/integration/include.js b/test/casperjs/integration/include.js index dfea8a32..c20ec782 100644 --- a/test/casperjs/integration/include.js +++ b/test/casperjs/integration/include.js @@ -27,8 +27,10 @@ function isChecked(selector) { function setPiskelFromGrid(grid) { casper.evaluate( 'function () {\ - var B = "#000000", T = Constants.TRANSPARENT_COLOR;\ - var frame = pskl.model.Frame.fromPixelGrid(' + grid + ');\ + var B = "#0000FF", T = Constants.TRANSPARENT_COLOR;\ + var R = "#FF0000", G = "#00FF00";\ + var grid = pskl.utils.FrameUtils.toFrameGrid(' + grid + ');\ + var frame = pskl.model.Frame.fromPixelGrid(grid);\ var layer = pskl.model.Layer.fromFrames("l1", [frame]);\ var piskel = pskl.model.Piskel.fromLayers([layer], 12, {name : "test", description : ""});\ pskl.app.piskelController.setPiskel(piskel);\ @@ -38,12 +40,17 @@ function setPiskelFromGrid(grid) { function piskelFrameEqualsGrid(grid, layer, frame) { return casper.evaluate( 'function () {\ - var B = "#000000", T = Constants.TRANSPARENT_COLOR;\ + var B = "#0000FF", T = Constants.TRANSPARENT_COLOR;\ + var R = "#FF0000", G = "#00FF00";\ var piskel = pskl.app.piskelController.getPiskel();\ var frame = piskel.getLayerAt(' + layer +').getFrameAt(' + frame + ');\ var grid = ' + grid +';\ var isValid = true;\ + var log = [];\ frame.forEachPixel(function (color, col, row) {\ + if (pskl.utils.colorToInt(color) !== pskl.utils.colorToInt(grid[row][col])) {\ + log.push(color, grid[row][col]);\ + }\ isValid = isValid && pskl.utils.colorToInt(color) === pskl.utils.colorToInt(grid[row][col]);\ });\ return isValid;\ @@ -57,6 +64,16 @@ function isDrawerExpanded() { }); } +/** + * Wait for the provided piskel specific event. + * + * @param {String} eventName + * name of the event to listen to + * @param {Function} onSuccess + * callback to call when the event is successfully catched + * @param {Function} onError + * callback to call when failing to get the event (most likely, timeout) + */ function waitForEvent(eventName, onSuccess, onError) { var cleanup = function () { casper.evaluate( @@ -89,3 +106,27 @@ function waitForEvent(eventName, onSuccess, onError) { });\ }'); } + +function replaceFunction(test, path, method) { + // Check the path provided corresponds to an existing method, otherwise the + // test probably needs to be updated. + test.assertEquals(evalLine('typeof ' + path),'function', + 'The prototype of GifExportController still contains downloadImageData_ as a function'); + + // Replace the method in content. + casper.evaluate('function () {' + path + ' = ' + method + '}'); +} + +function setPiskelFromImageSrc(src) { + casper.evaluate( + 'function () {\ + pskl.utils.FrameUtils.createFromImageSrc("' + src + '", false, function (frame) {\ + var layer = pskl.model.Layer.fromFrames("l1", [frame]);\ + var piskel = pskl.model.Piskel.fromLayers([layer], 12, {\ + name: "piskel",\ + description: "description"\ + });\ + pskl.app.piskelController.setPiskel(piskel);\ + });\ + }'); +} diff --git a/test/casperjs/integration/settings/test-export-gif-scale.js b/test/casperjs/integration/settings/test-export-gif-scale.js new file mode 100644 index 00000000..235932fa --- /dev/null +++ b/test/casperjs/integration/settings/test-export-gif-scale.js @@ -0,0 +1,116 @@ +/* globals casper, setPiskelFromGrid, isDrawerExpanded, getValue, isChecked, + evalLine, waitForEvent, replaceFunction, piskelFrameEqualsGrid, setPiskelFromImageSrc */ + +casper.test.begin('Simple GIF (<256 colors) export test, with 2x scaling', 16, function(test) { + test.timeout = test.fail.bind(test, ['Test timed out']); + + function onTestStart() { + test.assertExists('#drawing-canvas-container canvas', 'Piskel ready, test starting'); + + test.assert(!isDrawerExpanded(), 'settings drawer is closed'); + + setPiskelFromGrid('['+ + '[R, G, B, T],' + + '[T, R, G, B],'+ + '[B, T, R, G],'+ + '[G, B, T, R],'+ + ']'); + + // Check the expected piskel was correctly loaded. + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getWidth()'), 4, 'Piskel width is now 4 pixels'); + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getHeight()'), 4, 'Piskel height is now 4 pixels'); + + // Open export panel. + test.assertDoesntExist('.settings-section-export', 'Check if export panel is closed'); + casper.click('[data-setting="export"]'); + + casper.waitForSelector('.settings-section-export', onExportPanelReady, test.timeout, 10000); + } + + function onExportPanelReady() { + test.assert(isDrawerExpanded(), 'settings drawer is expanded'); + test.assertExists('.settings-section-export', 'Check if export panel is opened'); + + // Override download method from GIF export controller to be able to retrieve the image + // data on the content document. + replaceFunction(test, + 'pskl.controller.settings.exportimage.GifExportController.prototype.downloadImageData_', + function (imageData) { + window.casperImageData = imageData; + var el = document.createElement("div"); + el.id = "casper-imagedata-ready"; + document.body.appendChild(el); + } + ); + + test.assertExists('[name="resize-width"]', 'The resize width input is available'); + casper.sendKeys('[name="resize-width"]', casper.page.event.key.Backspace); + casper.sendKeys('[name="resize-width"]', "8"); + + test.assertEquals(getValue('[name="scale-input"]'), "2", 'Resize scale is 2'); + test.assertEquals(getValue('[name="resize-height"]'), "8", 'Resize height is 8px'); + test.assertEquals(getValue('[name="resize-height"]'), "8", 'Resize height is 8px'); + + casper.echo('Clicking on Download GIF button'); + test.assertExists('.gif-download-button', 'The gif download button is available'); + casper.click('.gif-download-button'); + + casper.echo('Wait for #casper-imagedata-ready'); + casper.waitForSelector('#casper-imagedata-ready', onImageDataReady, test.timeout, 10000); + } + + function onImageDataReady() { + casper.echo('Found casper-imagedata-ready element'); + + // cleanup + casper.evaluate(function () { + document.body.removeChild(document.getElementById('casper-imagedata-ready')); + }); + + // Check the exported gif is valid + var imageData = evalLine('window.casperImageData'); + test.assert(imageData.indexOf('data:image/gif;base64') === 0, 'The gif image data was generated'); + + // Recreate a new piskel from the source + waitForEvent('PISKEL_RESET', onPiskelReset, test.timeout); + setPiskelFromImageSrc(imageData); + } + + function onPiskelReset() { + casper.echo('Received PISKEL_RESET event after loading piskel from scaled GIF source'); + + // Check the expected piskel was correctly loaded. + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getWidth()'), 8, 'Piskel width is now 8 pixels'); + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getHeight()'), 8, 'Piskel height is now 8 pixels'); + + // Check that the piskel content has been resized. + test.assert(piskelFrameEqualsGrid('['+ + '[R, R, G, G, B, B, T, T],' + + '[R, R, G, G, B, B, T, T],' + + '[T, T, R, R, G, G, B, B],' + + '[T, T, R, R, G, G, B, B],' + + '[B, B, T, T, R, R, G, G],' + + '[B, B, T, T, R, R, G, G],' + + '[G, G, B, B, T, T, R, R],' + + '[G, G, B, B, T, T, R, R],' + + ']', 0, 0), 'Scaled piskel content is as expected'); + + // Click on export again to close the settings drawer. + casper.click('[data-setting="export"]'); + casper.waitForSelector('[data-pskl-controller="settings"]:not(.expanded)', onDrawerClosed, test.timeout, 10000); + } + + function onDrawerClosed() { + test.assert(!isDrawerExpanded(), 'settings drawer is closed'); + } + + casper + .start(casper.cli.get('baseUrl')+"/?debug") + .then(function () { + casper.echo("URL loaded"); + casper.waitForSelector('#drawing-canvas-container canvas', onTestStart, test.timeout, 10000); + }) + .run(function () { + test.done(); + }); +}); diff --git a/test/casperjs/integration/settings/test-export-gif-simple.js b/test/casperjs/integration/settings/test-export-gif-simple.js new file mode 100644 index 00000000..e79e85ca --- /dev/null +++ b/test/casperjs/integration/settings/test-export-gif-simple.js @@ -0,0 +1,105 @@ +/* globals casper, setPiskelFromGrid, isDrawerExpanded, getValue, isChecked, + evalLine, waitForEvent, replaceFunction, piskelFrameEqualsGrid, setPiskelFromImageSrc */ + +casper.test.begin('Simple GIF (<256 colors) export test', 14, function(test) { + test.timeout = test.fail.bind(test, ['Test timed out']); + + function onTestStart() { + test.assertExists('#drawing-canvas-container canvas', 'Piskel ready, test starting'); + + test.assert(!isDrawerExpanded(), 'settings drawer is closed'); + + setPiskelFromGrid('['+ + '[R, G, B, T],' + + '[T, R, G, B],'+ + '[B, T, R, G],'+ + '[G, B, T, R],'+ + ']'); + + // Check the expected piskel was correctly loaded. + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getWidth()'), 4, 'Piskel width is now 4 pixels'); + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getHeight()'), 4, 'Piskel height is now 4 pixels'); + + // Open export panel. + test.assertDoesntExist('.settings-section-export', 'Check if export panel is closed'); + casper.click('[data-setting="export"]'); + + casper.waitForSelector('.settings-section-export', onExportPanelReady, test.timeout, 10000); + } + + function onExportPanelReady() { + test.assert(isDrawerExpanded(), 'settings drawer is expanded'); + test.assertExists('.settings-section-export', 'Check if export panel is opened'); + + // Override download method from GIF export controller to be able to retrieve the image + // data on the content document. + replaceFunction(test, + 'pskl.controller.settings.exportimage.GifExportController.prototype.downloadImageData_', + function (imageData) { + window.casperImageData = imageData; + var el = document.createElement("div"); + el.id = "casper-imagedata-ready"; + document.body.appendChild(el); + } + ); + + casper.echo('Clicking on Download GIF button'); + test.assertExists('.gif-download-button', 'The gif download button is available'); + casper.click('.gif-download-button'); + + casper.echo('Wait for #casper-imagedata-ready'); + casper.waitForSelector('#casper-imagedata-ready', onImageDataReady, test.timeout, 10000); + } + + function onImageDataReady() { + casper.echo('Found casper-imagedata-ready element'); + + // cleanup + casper.evaluate(function () { + document.body.removeChild(document.getElementById('casper-imagedata-ready')); + }); + + var imageData = evalLine('window.casperImageData'); + + // Check the exported gif is valid + test.assert(imageData.indexOf('data:image/gif;base64') === 0, 'The gif image data was generated'); + + // Recreate a new piskel from the source + waitForEvent('PISKEL_RESET', onPiskelReset, test.timeout); + setPiskelFromImageSrc(imageData); + } + + function onPiskelReset() { + casper.echo('Received PISKEL_RESET event after loading piskel from GIF source'); + + // Check the expected piskel was correctly loaded. + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getWidth()'), 4, 'Piskel width is now 4 pixels'); + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getHeight()'), 4, 'Piskel height is now 4 pixels'); + + // Check that the piskel content has been resized. + test.assert(piskelFrameEqualsGrid('['+ + '[R, G, B, T],' + + '[T, R, G, B],' + + '[B, T, R, G],' + + '[G, B, T, R],' + + ']', 0, 0), 'Imported piskel content is as expected'); + + // Click on export again to close the settings drawer. + casper.click('[data-setting="export"]'); + casper.waitForSelector('[data-pskl-controller="settings"]:not(.expanded)', onDrawerClosed, test.timeout, 10000); + } + + function onDrawerClosed() { + test.assert(!isDrawerExpanded(), 'settings drawer is closed'); + } + + casper + .start(casper.cli.get('baseUrl')+"/?debug") + .then(function () { + casper.echo("URL loaded"); + casper.waitForSelector('#drawing-canvas-container canvas', onTestStart, test.timeout, 10000); + }) + .run(function () { + test.done(); + }); +}); diff --git a/test/casperjs/integration/settings/test-export-gif.js b/test/casperjs/integration/settings/test-export-gif.js index c3b491d2..dac8b1a1 100644 --- a/test/casperjs/integration/settings/test-export-gif.js +++ b/test/casperjs/integration/settings/test-export-gif.js @@ -1,45 +1,7 @@ -/* globals casper, setPiskelFromGrid, isDrawerExpanded, getValue, isChecked, evalLine, waitForEvent */ +/* globals casper, setPiskelFromGrid, isDrawerExpanded, getValue, isChecked, + evalLine, waitForEvent, replaceFunction, setPiskelFromImageSrc */ -function setPiskelFromImageSrc(src) { - casper.evaluate( - 'function () {\ - pskl.utils.FrameUtils.createFromImageSrc("' + src + '", false, function (frame) {\ - var layer = pskl.model.Layer.fromFrames("l1", [frame]);\ - var piskel = pskl.model.Piskel.fromLayers([layer], 12, {\ - name: "piskel",\ - description: "description"\ - });\ - pskl.app.piskelController.setPiskel(piskel);\ - });\ - }'); -} - -// Source for a base64 encoded PNG, 20x20, with 400 different colors. -var src = [ - 'data:image/png;base64,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'].join(''); - -casper.test.begin('GIF export Test', 11, function(test) { +casper.test.begin('Complex GIF export test', 11, function(test) { test.timeout = test.fail.bind(test, ['Test timed out']); function onTestStart() { @@ -67,25 +29,20 @@ casper.test.begin('GIF export Test', 11, function(test) { test.assert(isDrawerExpanded(), 'settings drawer is expanded'); test.assertExists('.settings-section-export', 'Check if export panel is opened'); - test.assertEquals( - evalLine('typeof pskl.controller.settings.exportimage.GifExportController.prototype.downloadImageData_'), - 'function', 'The prototype of GifExportController still contains downloadImageData_ as a function'); + // Override download method from GIF export controller to be able to retrieve the image + // data on the content document. + replaceFunction(test, + 'pskl.controller.settings.exportimage.GifExportController.prototype.downloadImageData_', + function (imageData) { + window.casperImageData = imageData; + var el = document.createElement("div"); + el.id = "casper-imagedata-ready"; + document.body.appendChild(el); + } + ); - // Override the downloadImageData_ method on the GifExportController - casper.evaluate( - 'function () {\ - pskl.controller.settings.exportimage.GifExportController.prototype.downloadImageData_ = function (imageData) {\ - window.casperImageData = imageData;\ - var el = document.createElement("div");\ - el.id = "casper-imagedata-ready";\ - document.body.appendChild(el);\ - };\ - }'); - - test.assertExists('.gif-download-button', 'The gif download button is available'); - - casper.echo(evalLine('caca.downloadImageData_ + ""')); casper.echo('Clicking on Download GIF button'); + test.assertExists('.gif-download-button', 'The gif download button is available'); casper.click('.gif-download-button'); casper.echo('Wait for #casper-imagedata-ready'); @@ -123,3 +80,28 @@ casper.test.begin('GIF export Test', 11, function(test) { test.done(); }); }); + +// Source for a base64 encoded PNG, 20x20, with 400 different colors. +var src = [ + 'data:image/png;base64,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'].join(''); diff --git a/test/casperjs/integration/settings/test-export-png-scale.js b/test/casperjs/integration/settings/test-export-png-scale.js new file mode 100644 index 00000000..7ac29edd --- /dev/null +++ b/test/casperjs/integration/settings/test-export-png-scale.js @@ -0,0 +1,120 @@ +/* globals casper, setPiskelFromGrid, isDrawerExpanded, getValue, isChecked, + evalLine, waitForEvent, piskelFrameEqualsGrid, replaceFunction, setPiskelFromImageSrc */ + +casper.test.begin('PNG export test, with 2x scaling', 16, function(test) { + test.timeout = test.fail.bind(test, ['Test timed out']); + + function onTestStart() { + test.assertExists('#drawing-canvas-container canvas', 'Piskel ready, test starting'); + + test.assert(!isDrawerExpanded(), 'settings drawer is closed'); + + // Setup test Piskel + setPiskelFromGrid('['+ + '[B, T],' + + '[T, B],' + + ']'); + + // Open export panel. + test.assertDoesntExist('.settings-section-export', 'Check if export panel is closed'); + casper.click('[data-setting="export"]'); + + casper.waitForSelector('.settings-section-export', onExportPanelReady, test.timeout, 10000); + } + + function onExportPanelReady() { + casper.echo('Export panel ready'); + + test.assert(isDrawerExpanded(), 'settings drawer is expanded'); + test.assertExists('.settings-section-export', 'Check if export panel is opened'); + + // Switch to PNG export tab. + test.assertDoesntExist('.export-panel-png', 'Check if PNG export panel is hidden'); + casper.click('[data-tab-id="png"]'); + + casper.waitForSelector('.export-panel-png', onPngExportTabReady, test.timeout, 10000); + } + + function onPngExportTabReady() { + casper.echo('Png export tab ready'); + + replaceFunction(test, + 'pskl.controller.settings.exportimage.PngExportController.prototype.downloadCanvas_', + function (canvas) { + window.casperImageData = canvas.toDataURL('image/png'); + var el = document.createElement("div"); + el.id = "casper-imagedata-ready"; + document.body.appendChild(el); + } + ); + + casper.echo('Test that the scaling works'); + + test.assertExists('[name="resize-width"]', 'The resize width input is available'); + casper.sendKeys('[name="resize-width"]', casper.page.event.key.Backspace); + casper.sendKeys('[name="resize-width"]', "4"); + + // Check the scale and height inputs have been synchronized as expected. + test.assertEquals(getValue('[name="scale-input"]'), "2", 'Resize scale is 2'); + test.assertEquals(getValue('[name="resize-height"]'), "4", 'Resize height is 4px'); + test.assertEquals(getValue('[name="resize-height"]'), "4", 'Resize height is 4px'); + + casper.echo('Clicking on Download PNG button'); + casper.click('.png-download-button'); + + casper.echo('Wait for #casper-imagedata-ready'); + casper.waitForSelector('#casper-imagedata-ready', onImageDataReady, test.timeout, 10000); + } + + function onImageDataReady() { + casper.echo('Found casper-imagedata-ready element'); + + // cleanup + casper.evaluate(function () { + document.body.removeChild(document.getElementById('casper-imagedata-ready')); + }); + + var imageData = evalLine('window.casperImageData'); + + // Check the exported gif is valid + test.assert(imageData.indexOf('data:image/png;base64') === 0, 'The png image data was generated'); + + // Recreate a new piskel from the source + waitForEvent('PISKEL_RESET', onPiskelReset, test.timeout); + setPiskelFromImageSrc(imageData); + } + + function onPiskelReset() { + casper.echo('Received PISKEL_RESET event after loading piskel from scaled GIF source'); + + // Check the expected piskel was correctly loaded. + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getWidth()'), 4, 'Piskel width is now 4 pixels'); + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getHeight()'), 4, 'Piskel height is now 4 pixels'); + + // Check that the piskel content has been resized. + test.assert(piskelFrameEqualsGrid('['+ + '[B, B, T, T],' + + '[B, B, T, T],' + + '[T, T, B, B],' + + '[T, T, B, B],' + + ']', 0, 0), 'Scaled piskel content is as expected'); + + // Click on export again to close the settings drawer. + casper.click('[data-setting="export"]'); + casper.waitForSelector('[data-pskl-controller="settings"]:not(.expanded)', onDrawerClosed, test.timeout, 10000); + } + + function onDrawerClosed() { + test.assert(!isDrawerExpanded(), 'settings drawer is closed'); + } + + casper + .start(casper.cli.get('baseUrl')+"/?debug") + .then(function () { + casper.echo("URL loaded"); + casper.waitForSelector('#drawing-canvas-container canvas', onTestStart, test.timeout, 10000); + }) + .run(function () { + test.done(); + }); +}); diff --git a/test/casperjs/integration/settings/test-export-png.js b/test/casperjs/integration/settings/test-export-png.js new file mode 100644 index 00000000..6fa3f3c6 --- /dev/null +++ b/test/casperjs/integration/settings/test-export-png.js @@ -0,0 +1,109 @@ +/* globals casper, setPiskelFromGrid, isDrawerExpanded, getValue, isChecked, + evalLine, waitForEvent, piskelFrameEqualsGrid, replaceFunction, setPiskelFromImageSrc */ + +casper.test.begin('PNG export test', 13, function(test) { + test.timeout = test.fail.bind(test, ['Test timed out']); + + function onTestStart() { + test.assertExists('#drawing-canvas-container canvas', 'Piskel ready, test starting'); + + test.assert(!isDrawerExpanded(), 'settings drawer is closed'); + + // Setup test Piskel + setPiskelFromGrid('['+ + '[B, T],' + + '[T, B],' + + ']'); + + // Open export panel. + test.assertDoesntExist('.settings-section-export', 'Check if export panel is closed'); + casper.click('[data-setting="export"]'); + + casper.waitForSelector('.settings-section-export', onExportPanelReady, test.timeout, 10000); + } + + function onExportPanelReady() { + casper.echo('Export panel ready'); + + test.assert(isDrawerExpanded(), 'settings drawer is expanded'); + test.assertExists('.settings-section-export', 'Check if export panel is opened'); + + // Switch to PNG export tab. + test.assertDoesntExist('.export-panel-png', 'Check if PNG export panel is hidden'); + casper.click('[data-tab-id="png"]'); + + casper.waitForSelector('.export-panel-png', onPngExportTabReady, test.timeout, 10000); + } + + function onPngExportTabReady() { + casper.echo('Png export tab ready'); + + replaceFunction(test, + 'pskl.controller.settings.exportimage.PngExportController.prototype.downloadCanvas_', + function (canvas) { + window.casperImageData = canvas.toDataURL('image/png'); + var el = document.createElement("div"); + el.id = "casper-imagedata-ready"; + document.body.appendChild(el); + } + ); + + test.assertExists('.png-download-button', 'The png download button is available'); + + casper.echo('Clicking on Download PNG button'); + casper.click('.png-download-button'); + + casper.echo('Wait for #casper-imagedata-ready'); + casper.waitForSelector('#casper-imagedata-ready', onImageDataReady, test.timeout, 10000); + } + + function onImageDataReady() { + casper.echo('Found casper-imagedata-ready element'); + + // cleanup + casper.evaluate(function () { + document.body.removeChild(document.getElementById('casper-imagedata-ready')); + }); + + var imageData = evalLine('window.casperImageData'); + + // Check the exported gif is valid + test.assert(imageData.indexOf('data:image/png;base64') === 0, 'The png image data was generated'); + + // Recreate a new piskel from the source + waitForEvent('PISKEL_RESET', onPiskelReset, test.timeout); + setPiskelFromImageSrc(imageData); + } + + function onPiskelReset() { + casper.echo('Received PISKEL_RESET event after loading piskel from GIF source'); + + // Check the expected piskel was correctly loaded. + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getWidth()'), 2, 'Piskel width is now 2 pixels'); + test.assertEquals(evalLine('pskl.app.piskelController.getPiskel().getHeight()'), 2, 'Piskel height is now 2 pixels'); + + // Check that the piskel content has been resized. + test.assert(piskelFrameEqualsGrid('['+ + '[B, T],' + + '[T, B],' + + ']', 0, 0), 'Imported piskel content is as expected'); + + // Click on export again to close the settings drawer. + casper.click('[data-setting="export"]'); + casper.waitForSelector('[data-pskl-controller="settings"]:not(.expanded)', onDrawerClosed, test.timeout, 10000); + } + + function onDrawerClosed() { + test.assert(!isDrawerExpanded(), 'settings drawer is closed'); + } + + casper + .start(casper.cli.get('baseUrl')+"/?debug") + .then(function () { + casper.echo("URL loaded"); + casper.waitForSelector('#drawing-canvas-container canvas', onTestStart, test.timeout, 10000); + }) + .run(function () { + test.done(); + }); +});